1679(次小生成樹&&MST的唯一性)
阿新 • • 發佈:2018-12-13
最小生成樹的唯一性,思路是先判斷每條邊是否有重邊,有的話flag=1,否則0.然後第一次求出最小生成樹,將結果記錄下來, 然後依次去掉第一次使用過的且含有重邊的邊,再求一次最小生成樹,若結果與第一次結果一樣,則不唯一。
#include<iostream> #include<cstdlib> #include<cstdio> #include<algorithm> using namespace std; struct node { int x,y,w; int flag,used,del; } e[10010]; int first=0,father[10010]; int n,m,cnt; bool cmp(node a,node b){ return a.w<b.w; } void init(){ for(int i=0;i<=10010;i++){ father[i]=i; } } int check(int x){ int r=x; while(r!=father[r]){ r=father[r]; } return r; } int combine(int l,int r){ int l1=check(l); int r1=check(r); if(l1!=r1){ father[l1]=r1; return 1; } return 0; } int kruskal(){ init(); int sum=0,num=0; for(int i=0;i<m;i++){ if(e[i].del==1)continue; if(combine(e[i].x,e[i].y)){ sum+=e[i].w; num++; if(first) e[i].used=1; } if(num>=n-1)break; } return sum; } int main(){ int t; cin>>t; while(t--){ cnt=0; cin>>n>>m; for(int i=0;i<m;i++){ cin>>e[i].x>>e[i].y>>e[i].w; e[i].del=0; e[i].used=0; e[i].flag=0; } for(int i=0;i<m;i++){ for(int j=0;j<m;j++){ if(i==j)continue; if(e[i].w==e[j].w) e[i].flag=1; } } sort(e,e+m,cmp); first=1; int ans=kruskal(); first=0; int flag=0; // cout<<"asd"<<endl; for(int i=0;i<m;i++){ if(e[i].used==1&&e[i].flag==1){ e[i].del=1; int ans1=kruskal(); // cout<<ans1<<endl; if(ans1==ans){ flag=1; puts("Not Unique!"); break; } } e[i].del=0; } // cout<<"asd"<<endl; if(!flag)cout<<ans<<endl; } return 0; }