标签:des style http color os io for cti
Description
Input
Output
Sample Input
2 3 3 1 2 1 2 3 2 3 1 3 4 4 1 2 2 2 3 2 3 4 2 4 1 2
Sample Output
3 Not Unique!
Source
题意:就是判断最小生成树是不是唯一的,换而言之就是最小生成树的一条边能不能被别的边代替
思路:先来一遍最小生成树,把加入最小生成树的边标记,然后一一去掉这条边,看看有没有边能代替这条边,也就是看最小生成树的值变不变
就说这么多了,应该清楚了吧,看代码吧
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 10005 struct stud{ int a,b,len; }f[N]; int father[N],vis[N],n,m; int sum; int cmp(stud a,stud b) { return a.len<b.len; } int cha(int x) { if(x!=father[x]) father[x]=cha(father[x]); return father[x]; } int fdd(int x) { int i; for(i=0;i<=n;i++) father[i]=i; int num=1,ans=0; for(i=0;i<m;i++) { if(i==x) continue; //该标记的边不加入生成树 int aa=cha(f[i].a); int bb=cha(f[i].b); if(aa!=bb) { father[aa]=bb; num++; ans+=f[i].len; if(num==n) break; } } if(num==n&&ans==sum) return 1; //记住必须是两个条件,缺一不可 return 0; } int main() { int t,i; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(i=0;i<m;i++) scanf("%d%d%d",&f[i].a,&f[i].b,&f[i].len); for(i=0;i<=n;i++) father[i]=i; sort(f,f+m,cmp); //按边排序 int num=1; memset(vis,0,sizeof(vis)); sum=0; for(i=0;i<m;i++) { int aa=cha(f[i].a); int bb=cha(f[i].b); if(aa!=bb) { father[aa]=bb; num++; vis[i]=1; //标记加入生成树的边 sum+=f[i].len; //最小生成树的值为sum if(num==n) break; //n个点,需要n-1条边(num初始值为1) } } int flag=0; for(i=0;i<m;i++) if(vis[i]) //如果这条边加入到生成树,就看看有么有边能代替他 if(fdd(i)) //如果能 break; break; if(i!=m) printf("Not Unique!\n"); else printf("%d\n",sum); } return 0; }
POJ 1679 The Unique MST,布布扣,bubuko.com
标签:des style http color os io for cti
原文地址:http://blog.csdn.net/u014737310/article/details/38355579