| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
此题很有问题.....用kruscal做的,不用sort就AC...加上sort就RE....附代码:
#include<cstdio>
#include<climits>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int N=207;
int max_[N][N]; // 最小权边邻接点集合,最小权边值集合
struct edge { // 边信息
int u,v,w;
friend bool operator<(edge const&L,edge const&R) {
return L.w<R.w;
}
} ;
struct edge_ {
int v,w;
edge_(int x,int y ) {
v = x; w = y;
}
};
vector<edge_> ve[N];
edge E[N*N];
bool e[N];
class UF { // 并查集
public:
void makeset(int i ) { parent[i] = i; rank[i] = 0; }
void Union(int x,int y) { link(Find(x),Find(y)); }
int Find(int x) {
if(parent[x]!=x) parent[x] = Find(parent[x]);
return parent[x];
}
bool Joint(int x,int y){ return Find(x)==Find(y); }
private:
int parent[N],rank[N];
void link(int x,int y) {
if(rank[y]<rank[x]) {
parent[y] = x;
}
else {
parent[x] = y;
if(rank[x]==rank[y]) ++rank[y];
}
}
};
int kruscal(edge*E,int n,int m)
{
UF uf;
for(int i=1;i<=n;++i) uf.makeset(i);
for(int i=0;i<m; ++i) e[i]=false;;
std::sort(E,E+m);
int sum = 0;
for(int i=0,j=0;i<m&&j<n-1;++i) {
int x=E[i].u;
int y=E[i].v;
if(!uf.Joint(x,y)) {
sum += E[i].w;
uf.Union(x,y);
ve[x].push_back(edge_(y,E[i].w));
ve[y].push_back(edge_(x,E[i].w));
e[i] = true;
++j ;
}
}
return sum;
}
void getmax_(int u,int n)
{
memset(max_[u],0xff,sizeof(max_[u]));
queue<int> Q;
Q.push(u);
while( !Q.empty() ) {
int v = Q.front() ; Q.pop();
for(int i=0;i<(int)ve[v].size();++i)
{
edge_ const &x = ve[v][i];
if(max_[u][x.v]==-1&&x.v!=u) {
if(u==v|| x.w>max_[u][v]) max_[u][x.v] = x.w;
else max_[u][x.v] = max_[u][v];
Q.push(x.v);
}
}
}
}
int mst_sec(edge*E,int n,int m,int sum)
{
for(int i=1;i<=n;++i) getmax_(i,n); // 求树上任意两点间的最大边权?
int mx=INT_MAX;
for(int i=0;i<m;++i) {
if( e[i] == false ) {
if(mx>E[i].w-max_[E[i].u][E[i].v])
mx=E[i].w-max_[E[i].u][E[i].v];
}
}
return sum - mx;
}
int main()
{
int n,m,test;
scanf("%d",&test);
for( ; test ; --test)
{
scanf("%d%d",&n,&m);
for(int i=0;i<m;++i)
{
int a,b,w;
scanf("%d%d%d",&a,&b,&w);
E[i].u = a; E[i].v = b; E[i].w = w;
}
int res = kruscal(E,n,m);
if(res == mst_sec(E,n,m,res)) printf("Not Unique!\n");
else printf("%d\n",res);
for(int i =1;i<=n;++i) ve[i].clear();
}
return 0;
}
Followed by:
Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator