标签:最小生成树
判断最小生成树是否唯一。
先扫一遍边,找出相等的边并标记 vis;
然后生成最小生成树,总权值为 ans,并记录下哪些边在第一次生成中使用了。use;
最后扫描所有边,有相等的,并且使用的边。把它标记为删除 del;然后生成最小生成树。
如果跟第一颗树权值一样,表明生成树不是唯一的。
#include<cstdio> #include<cstring> #include<string> #include<queue> #include<algorithm> #include<queue> #include<map> #include<stack> #include<iostream> #include<list> #include<set> #include<cmath> #define INF 0x7fffffff #define eps 1e-6 using namespace std; int n,m; int fa[101]; struct lx { int u,v,len; } l[101*50]; int father(int x) { if(x!=fa[x]) return fa[x]=father(fa[x]); } bool cmp(lx a,lx b) { return a.len<b.len; } bool vis[101*50]; bool use[101*50]; bool del[101*50]; int Kruskal(bool flag) { for(int i=0; i<=n; i++) fa[i]=i; int point=1,ans=0; for(int i=0; i<m; i++) { if(del[i])continue; int u=father(l[i].u); int v=father(l[i].v); if(u==v)continue; fa[u]=v; point++; if(flag)use[i]=1; ans+=l[i].len; if(point>=n)break; } return ans; } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(int i=0; i<m; i++) scanf("%d%d%d",&l[i].u,&l[i].v,&l[i].len); sort(l,l+m,cmp); memset(vis,0,sizeof(vis)); memset(use,0,sizeof(use)); memset(del,0,sizeof(del)); for(int i=0; i<m-1; i++) if(l[i].len==l[i+1].len)vis[i]=vis[i+1]=1; int bt1=Kruskal(1); bool flag=1; for(int i=0; i<m; i++) { if(vis[i]&&use[i]) { del[i]=1; int bt2=Kruskal(0); if(bt1==bt2) { flag=0; break; } del[i]=0; } } if(flag)printf("%d\n",bt1); else printf("Not Unique!\n"); } }
POJ 1679 The Unique MST,布布扣,bubuko.com
标签:最小生成树
原文地址:http://blog.csdn.net/dongshimou/article/details/37049123