POJ-1679-The Unique MST
http://poj.org/problem?id=1679
次小產生樹,prim稍作改變即可,每次加入新的頂點時,如果有不止一條權值最小的最短邊,則說明最小產生樹不只一種
#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>using namespace std;#define N 105#define INF 99999999int map[N][N];int dis[N];int visit[N];int n;void prim(){int i,j,v,min,k,flag,sum;for(i=1;i<=n;i++)dis[i]=map[1][i];flag=0;sum=0;memset(visit,0,sizeof(visit));for(i=1;i<=n;i++){min=INF;for(j=1;j<=n;j++)if(!visit[j]&&dis[j]<min){min=dis[j];v=j;}k=0; for(j=1;j<=n;j++)if(visit[j]&&map[v][j]==min)k++;if(k>1){flag=1;break;}visit[v]=1;sum+=min;for(j=1;j<=n;j++)if(!visit[j]&&dis[j]>map[v][j])dis[j]=map[v][j];}if(flag)printf("Not Unique!\n");elseprintf("%d\n",sum);}int main(){int t;int i,j,m;int a,b,c;scanf("%d",&t);while(t--){scanf("%d%d",&n,&m);for(i=1;i<=n;i++)for(j=1;j<=n;j++){map[i][j]=INF;if(i==j)map[i][j]=0;}while(m--){scanf("%d%d%d",&a,&b,&c);if(map[a][b]>c){map[a][b]=map[b][a]=c;}}prim();}return 0;}
Kruskal演算法也可以,先構造一個最小產生樹,並且記錄所有的邊,然後刪除任一條邊,重新構造次小產生樹,若存在次小產生樹的權值和與最小產生的權值和相等,則說明最小產生樹不只一種
#include<stdio.h>#include<string.h>#include<stdlib.h>#define INF 0x7fffffffstruct cam{int x;int y;int len;}list[20005];int n,m,t;int id[20005];int f[20005];int cmp(const void *a,const void *b){return (*(struct cam *)a).len-(*(struct cam *)b).len;}void init(){for(int i=1;i<=n;i++)f[i]=i;}int find(int x){int r=x;while(f[r]!=r)r=f[r];f[x]=r;return f[x];}void Union(int x,int y){int xx,yy;xx=find(x);yy=find(y);if(xx!=yy)f[xx]=yy;}int kruskal(){int i,ans,sum;int a,b;init();sum=0;ans=0;t=0;for(i=0;i<m;i++){a=list[i].x;b=list[i].y;if(find(a)!=find(b)){Union(a,b);ans+=list[i].len;sum++; id[t++]=i; if(sum==n-1) break;}}if(sum==n-1)return ans;return -1;}int kruskalci(int k){ int i,ans,sum;int a,b;init();sum=0;ans=0;for(i=0;i<m;i++){if(i==k)continue;a=list[i].x;b=list[i].y;if(find(a)!=find(b)){Union(a,b);ans+=list[i].len;sum++;if(sum==n-1)break;}}if(sum==n-1)return ans;return -1;}int main(){int tt,i,min,flag,temp,Min;scanf("%d",&tt);while(tt--){memset(id,0,sizeof(id));memset(list,0,sizeof(list));scanf("%d%d",&n,&m);for(i=0;i<m;i++)scanf("%d%d%d",&list[i].x,&list[i].y,&list[i].len);qsort(list,m,sizeof(struct cam),cmp);min=kruskal();Min=INF;for(i=0;i<t;i++){temp=kruskalci(id[i]);if(temp!=-1&&temp<Min)Min=temp;}if(Min==min)printf("Not Unique!\n");elseprintf("%d\n",min);}system("pause");return 0;}