PKU 1679 The Unique MST(解题报告)

思路是先找出最小生成树,并记录每条遍,,要想说明是唯一的最小生成树,那么他的每条边都是必不可少的,然后我们可以枚举所有最小生成树的边 ,依次去掉,看是否还能不能组成一棵相同权值和的mst。就是因为当初的一点点儿错误导致 ,一周了将近,才拿出来,一眼看出bug!

#include<iostream>#include<string.h>#include<queue>#include<algorithm>using namespace std;const int M=103;int F[M];int r[M];int n,m,t,cnt;int res,ans;struct edge{int u,v,w;} per[M*M*M];bool cmp(edge a,edge b){return a.w<b.w;}void init(){for(int i=1; i<=n; i++){F[i]=i;r[i]=1;}}//int Find(int x)//{// if(x!=F[x])//F[x]=Find(F[x]);//return F[x];//}int Find(int x){int r=x;while(r!=F[r]){r=F[r];}int k=x;while(k!=r){int t=F[k];F[k]=r;k=t;}return r;}bool union_set(int u,int v){int tx=Find(u);int ty=Find(v);if(tx==ty)return false;else if(r[tx]>r[ty])F[ty]=tx;else if(r[tx]<r[ty])F[tx]=ty;else{F[tx]=ty;r[ty]++;}return true;}int main(){cin>>t;while(t–){cin>>n>>m;queue<int>dict;for(int i=0; i<m; i++)cin>>per[i].u>>per[i].v>>per[i].w;sort(per,per+m,cmp);init();cnt=0;res=0;for(int i=0; i<m; i++){if(union_set(per[i].u,per[i].v)){cnt++;dict.push(i);res+=per[i].w;if(cnt==n-1)break;}}int flag=0;while(!dict.empty()){cnt=0;ans=0;init();int k=dict.front();dict.pop();for(int i=0; i<m; i++){if(i==k)continue;if(union_set(per[i].u,per[i].v)){cnt++;ans+=per[i].w;if(cnt==n-1){if(ans==res){flag=1;break;}}}}if(flag){cout<<"Not Unique!"<<endl;break;}}if(!flag)cout<<res<<endl;}return 0;}

有事者,事竟成;破釜沉舟,百二秦关终归楚;苦心人,

PKU 1679 The Unique MST(解题报告)

相关文章:

你感兴趣的文章:

标签云: