传送门:The Unique MST
题意:判断最小生成树是否唯一。
分析:先求出原图的最小生成树,然后枚举删掉最小生成树的边,重做kruskal,看新的值和原值是否一样,一样的话最小生成树不唯一。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include<vector> #define LL long long #define INF 111111111 #define N 1010 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; struct node { int u,v,w; bool operator<(const node &a)const { return w<a.w; } }s[N*N]; int fa[N],path[N],n,m,mst,flag; void init() { for(int i=1;i<=n;i++) fa[i]=i; } int find(int x) { return x==fa[x]?x:fa[x]=find(fa[x]); } void krustal() { int cnt=0; mst=0;init(); for(int i=0;i<m;i++) { int a=find(s[i].u); int b=find(s[i].v); if(a==b)continue; fa[a]=b; path[cnt++]=i; mst+=s[i].w; } for(int i=0;i<cnt;i++) { int sum=0,num=0; init(); for(int j=0;j<m;j++) { if(j==path[i])continue; int a=find(s[j].u); int b=find(s[j].v); if(a==b)continue; fa[a]=b; sum+=s[j].w; num++; } if(num==n-1&&sum==mst){flag=0;return;} } } 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",&s[i].u,&s[i].v,&s[i].w); } sort(s,s+m); flag=1; krustal(); if(flag) printf("%d ",mst); else printf("Not Unique! "); } }