POJ 1679 The Unique MST
判断最小生成树是否唯一:
先求一遍MST,每次删去MST的一条边,求MST,如果发现有一次求出来的权值之和和一开始的一样,那么就不唯一了。
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int maxn=111; int n,m; struct Edge { int from,to,w; } edge[maxn*maxn]; int Father[maxn]; bool cmp(const Edge&a,const Edge&b) { return a.w<b.w; } int Find(int x) { if(x!=Father[x]) Father[x]=Find(Father[x]); return Father[x]; } int flag[maxn*maxn]; int fail[maxn*maxn]; int FAIL; int main() { int TTT; scanf("%d",&TTT); while(TTT--) { int i,j,ii; scanf("%d%d",&n,&m); for(i=0; i<=n; i++) Father[i]=i; memset(flag,0,sizeof(flag)); memset(fail,0,sizeof(fail)); FAIL=0; for(i=0; i<m; i++) scanf("%d%d%d",&edge[i].from,&edge[i].to,&edge[i].w); sort(edge,edge+m,cmp); int W=0; for(i=0; i<m; i++) { int u=Find(edge[i].from); int v=Find(edge[i].to); u=Find(u); v=Find(v); if(u!=v) { flag[i]=1; Father[u]=v; W=W+edge[i].w; } } for(ii=0; ii<m; ii++) { if(flag[ii]) { int X=0; int JIHE=n; fail[ii]=1; for(i=0; i<=n; i++) Father[i]=i; for(i=0; i<m; i++) { if(fail[i]) continue; int u=Find(edge[i].from); int v=Find(edge[i].to); u=Find(u); v=Find(v); if(u!=v) { JIHE--; Father[u]=v; X=X+edge[i].w; } } if(X==W&&JIHE==1) { FAIL=1; break; } fail[ii]=0; } } if(FAIL==1) printf("Not Unique!\n"); else printf("%d\n",W); } return 0; }