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 99999999 int 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"); else printf("%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 0x7fffffff struct 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"); else printf("%d\n",min); } system("pause"); return 0; }