它的结论是最小生成树是独一无二的。
先扫在边缘。确定双方平等和标记 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 ",bt1); else printf("Not Unique! "); } }
版权声明:本文博客原创文章。博客,未经同意,不得转载。