POJ 1679 The Unique MST (prim判斷最小生成樹是否唯一)
阿新 • • 發佈:2019-02-08
思路:
在prim演算法中,假設有a,b,c三個點。當更新加入c點時,若ac和bc的權值都為最小值,說明最小生成樹不唯一。
理由很簡單,當存在兩個最小權值時,abc和acb都是最小生成樹。
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<queue> #include<cstring> using namespace std; const int N=105; #define inf 0x3f3f3f3f int n,m,vis[N]; int dis[N],ma[N][N],cost,flag; void prim(){ for(int i=1;i<=n;i++){ dis[i]=ma[1][i]; vis[i]=0; } dis[1]=0; vis[1]=1; for(int i=1;i<=n;i++){ int mi=inf; int mb; for(int j=1;j<=n;j++){ if(!vis[j]&&dis[j]<mi){ mi=dis[j]; mb=j; } } if(mi==inf) break; int ce=0; for(int j=1;j<=n;j++){ if(vis[j]&&ma[mb][j]==mi)//檢查最小權值的邊個數,若超過一個則最小生成樹不唯一 ce++; } if(ce>1) { flag=0; return; } vis[mb]=1; cost+=dis[mb]; for(int i=1;i<=n;i++){ if(!vis[i]&&ma[mb][i]<dis[i]){ dis[i]=ma[mb][i]; } } } } int main(){ int T; scanf("%d",&T); while(T--){ cost=0; scanf("%d%d",&n,&m); int a,b,c; memset(ma,0x3f3f3f3f,sizeof(ma)); for(int i=1;i<=m;i++){ scanf("%d%d%d",&a,&b,&c); ma[a][b]=ma[b][a]=c; } flag=1; prim(); if(flag) printf("%d\n",cost); else puts("Not Unique!"); } return 0; }