Input
Output
Sample Input
2 3 3 1 2 1 2 3 2 3 1 3 4 4 1 2 2 2 3 2 3 4 2 4 1 2
Sample Output
3 Not Unique!
题解:首先算出最小生成树的权值和ans,然后枚举删除最小生成树中的每一条边,若还可以达到相同的效果,就说明最小生成树不唯一,
因为两个不同的最小生成树至少有一条边不同,所以我们才可以枚举删除每一条边.
#include<iostream> #include<vector> #include<algorithm> #include<stdio.h> using namespace std; typedef long long ll; const int maxn=100010; int f[maxn]; struct node { int u,v,w; bool operator < (const node &r)const{ return w<r.w; } }q[maxn]; int Find(int x) { return f[x]==x?x:f[x]=Find(f[x]); } int Merge(int u,int v) { u=Find(u); v=Find(v); if(u!=v)return f[u]=v,1; return 0; } vector<int>v; int main() { int T; cin>>T; while(T--){ v.clear(); int n,m; cin>>n>>m; for(int i=1;i<=n;i++)f[i]=i; for(int i=1;i<=m;i++){ cin>>q[i].u>>q[i].v>>q[i].w; } sort(q+1,q+1+m); int ans=0; for(int i=1;i<=m;i++){ int x=Merge(q[i].u,q[i].v); if(x){ v.push_back(i); ans+=q[i].w; } } int flag=1; for(int i=0;i<v.size();i++){ int sum=0,cnt=0; for(int j=1;j<=n;j++)f[j]=j; for(int j=1;j<=m;j++){ if(j==v[i])continue; int x=Merge(q[j].u,q[j].v); if(x){ sum+=q[j].w; cnt++; } } if(cnt==n-1&&ans==sum){ flag=0; break; } } if(flag)cout<<ans<<endl; else printf("Not Unique!\n"); } return 0; }
K - The Unique MST (最小生成树的唯一性)
原文:https://www.cnblogs.com/cherish-lin/p/11332866.html