poj1679(判断最小生成树是否唯一)
题意:给出n个点,m条边,要你判断最小生成树是否唯一。
思路:先做一次最小生成树操作,标记选择了的边,然后枚举已经被标记了的边,判断剩下的边组成的最小生成树是否与前面的相等,相等,则不唯一,否则唯一......
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; struct node { int v1,v2; int dis; int flg; } s[10000]; int cmp(const node a,const node b) { if(a.dis<b.dis) return 1; else return 0; } int father[200],n; int kruskal(int num,int m) { int ans=0,cnt=1; for(int i=0; i<m; i++) { if(i==num) continue; int s1=father[s[i].v1]; int s2=father[s[i].v2]; if(s1!=s2) { ans+=s[i].dis; //s[i].flg=1; cnt++; father[s2]=s1; for(int j=0; j<=n; j++) if(father[j]==s2) father[j]=s1; } } if(cnt!=n) return -1; else return ans; } int main() { int text; scanf("%d",&text); while(text--) { int m; int ans=0; scanf("%d%d",&n,&m); for(int i=0; i<=n; i++) father[i]=i; for(int i=0; i<m; i++) { scanf("%d%d%d",&s[i].v1,&s[i].v2,&s[i].dis); s[i].flg=0; } sort(s,s+m,cmp); int cnt=1; for(int i=0; i<m; i++) { int s1=father[s[i].v1]; int s2=father[s[i].v2]; if(s1!=s2) { ans+=s[i].dis; s[i].flg=1; cnt++; father[s2]=s1; for(int j=0; j<=n; j++) if(father[j]==s2) father[j]=s1; } } int w=0; for(int i=0; i<m; i++) { if(s[i].flg==0) continue; int sum=0; for(int j=0;j<=n;j++) father[j]=j; sum=kruskal(i,m); //printf("sum==%d\n",sum); if(sum==ans) { w=1; break; } } if(w==1) printf("Not Unique!\n"); else printf("%d\n",ans); } return 0; }
朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。