poj (简单题:kruskal判断最小生成树是否唯一--求次小生成树 )
来源:互联网 发布:淘宝达人如何加粉丝 编辑:程序博客网 时间:2024/05/16 02:56
#include<iostream>#include<cstdio>#include<cstring>#include<set>#include<cstdio>#include<string>#include<map>#include<algorithm>using namespace std;const int inf=999999;const int maxn=10000;int n,m;struct EDGE{ int u,v,len; int vis;}edge[maxn*100];int fa[maxn];int vv[maxn];bool cmp(EDGE a,EDGE b){ return a.len<b.len;}int findx(int a){ if(fa[a]==a) return a; else return findx(fa[a]);}void init(){ for(int i=0;i<=n;i++) { fa[i]=i; }}void Union(int a,int b){ int aa=findx(a); int bb=findx(b); if(aa<bb) fa[bb]=aa; else fa[aa]=bb;}int kruskal(){ int k=0; init(); int sum=0; for(int i=0;i<m;i++) { int aa=edge[i].u; int bb=edge[i].v; if(findx(aa)!=findx(bb)) { k++; edge[i].vis=1; sum+=edge[i].len; Union(aa,bb); } } if(k<n-1) return 0; else return sum;}int MMST(){ init(); int sum=0; int k=0; for(int i=0;i<m;i++) { if(!vv[i]) { int aa=edge[i].u; int bb=edge[i].v; if(findx(aa)!=findx(bb)) { k++; sum+=edge[i].len; Union(aa,bb); } } } if(k<n-1) return inf; else return sum;}int main(){ int cas; cin>>cas; while(cas--) { cin>>n>>m; memset(vv,0,sizeof(vv)); for(int i=0;i<m;i++) { cin>>edge[i].u>>edge[i].v>>edge[i].len; edge[i].vis=0; } sort(edge,edge+m,cmp); int sum=kruskal(); int ans=inf; for(int i=0;i<m;i++) { if(edge[i].vis) { vv[i]=1; int tmp=MMST(); ans=min(ans,tmp); vv[i]=0; } } if(ans==sum) cout<<"Not Unique!" <<endl; else cout<<sum<<endl; } return 0;}