POJ-1679 The Unique MST (判斷最小生成樹的唯一性)
阿新 • • 發佈:2018-10-02
href target tin cout strong using \n ren string
<題目鏈接>
題目大意:
給定一張無向圖,判斷其最小生成樹是否唯一。
解題分析:
對圖中每條邊,掃描其它邊,如果存在相同權值的邊,則標記該邊;用kruskal求出MST。
如果MST中無標記的邊,則該MST唯一;否則,在MST中依次去掉標記的邊,再求MST,若求得MST權值和原來的MST 權值相同,則MST不唯一。
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N=11000; int n,m,cnt; int parent[N]; bool flag; struct EDGE { int u,v,w; int eq,used,del; } edge[N]; bool cmp(EDGE a,EDGE b) { return a.w<b.w; } int Find(int x) { if(parent[x] != x) parent[x] = Find(parent[x]); return parent[x]; } void Union(int x,int y) { x = Find(x); y = Find(y);if(x == y) return; parent[y] = x; } int Kruskal(){ for(int i=0; i<=10005; i++)parent[i]=i; int sum=0,num=0; for(int i=0;i<m;i++){ if(edge[i].del==1)continue; int u=edge[i].u;int v=edge[i].v;int w=edge[i].w; if(Find(u)!=Find(v)){ sum+=w; if(!flag)edge[i].used=1; num++; Union(u,v); } if(num>=n-1)break; } return sum; } int main() { int t,d; cin>>t; while(t--) { cnt=0; cin>>n>>m; for(int i=0; i<m; i++) { cin>>edge[i].u>>edge[i].v>>edge[i].w; edge[i].del=0; edge[i].used=0; edge[i].eq=0; //判斷是否有和它長度相同的邊 } for(int i=0;i<m;i++){ for(int j=0;j<m;j++){ if(i==j)continue; if(edge[i].w==edge[j].w)edge[i].eq=1; } } sort(edge,edge+m,cmp); flag=false; cnt=Kruskal(); flag=true; bool fp=false; for(int i=0;i<m;i++){ if(edge[i].used==1&&edge[i].eq==1){ edge[i].del=1; int s=Kruskal(); if(s==cnt){ fp=true; printf("Not Unique!\n"); break; } edge[i].del=0; } } if(!fp)cout<<cnt<<endl; } return 0; }
2018-10-01
POJ-1679 The Unique MST (判斷最小生成樹的唯一性)