poj 1679 The Unique MST ([kuangbin带你飞]专题八 生成树 )
题目大意:给你一个无向图,问如果这个无向图的最小生成树是唯一的就输出最小生成树的权值,否则输出Not Unique!
解题思路,求次小生成树,如果次小生成树中有何最小的权值一样的,则生成树不唯一,否则唯一用Kruskal,求最小生成树,然后枚举其中一个边去掉以后(n-1条),再求最小生成树,然后和原来的权值比较,
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=100+10; int n,m; struct Node{ int u,v; int cost; }node[maxn*maxn]; bool cmd(Node a,Node b){ return a.cost<b.cost; } int s_tree[maxn]; int pa[maxn]; int find(int x){ if(pa[x]==x) return x; else return pa[x]=find(pa[x]); } void join(int x,int y){ int root1=find(x); int root2=find(y); if(root1!=root2){ pa[root2]=root1; } } bool same(int x,int y){ return find(x)==find(y); } void Kruskal(){ for(int i=0;i<=n;i++){ pa[i]=i; } memset(s_tree,0,sizeof(s_tree)); int k=0; int ans=0,ans1=0; for(int i=0;i<m &&k<n-1; i++){ int u,v; u=node[i].u; v=node[i].v; if(!same(u,v)){ ans+=node[i].cost; join(u,v); s_tree[k++]=i; } } int k1=0; for(int i=0;i<n-1;i++){ ans1=0; k1=0; for(int j=0;j<=n;j++) pa[j]=j; for(int j=0;j<m;j++){ if(s_tree[i]==j) continue; int u=node[j].u; int v=node[j].v; if(!same(u,v)){ k1++; ans1+=node[j].cost; join(u,v); } } if(k1!=n-1) continue; if(ans==ans1){ printf("Not Unique!\n"); return ; } } printf("%d\n",ans); } int main(){ int t; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); for(int i=0;i<m;i++){ int u,v,cost; scanf("%d%d%d",&u,&v,&cost); node[i].u=u; node[i].v=v; node[i].cost=cost; } sort(node,node+m,cmd); Kruskal(); } return 0; }