1. 程式人生 > >POJ-1679 The Unique MST (判斷最小生成樹的唯一性)

POJ-1679 The Unique MST (判斷最小生成樹的唯一性)

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 (判斷最小生成樹的唯一性)