思路:
(1)对图中每条边,扫描其他边,如果存在相同权值的边,则对该边做标记。
(2)然后用Kruskal求MST。
(3)求得MST后,如果该MST中未包含做了标记的边,即可判定MST唯一,如果包含了做了标记的边,则依次去掉这些再求MST,如果求的MST权值和原MST权值相同,即可判定MST不唯一。
代码:
1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <queue> 7 using namespace std; 8 const int maxn=101; 9 const int maxm=10001; 10 struct node 11 { 12 int u; 13 int v; 14 int w; 15 int equal; 16 int used; 17 int del; 18 }edge[maxm]; 19 int parent[maxn]; 20 int n,m; 21 bool first; 22 void init() 23 { 24 for(int i=0;i<=n;i++) 25 { 26 parent[i]=-1; 27 } 28 } 29 int find(int x) 30 { 31 int s; 32 for(s=x;parent[s]>=0;s=parent[s]); 33 while(s!=x) 34 { 35 int temp=parent[x]; 36 parent[x]=s; 37 x=temp; 38 } 39 return s; 40 } 41 void merge(int x,int y) 42 { 43 int x1=find(x); 44 int y1=find(y); 45 int temp=parent[x1]+parent[y1];//两个集合节点个数之和(<0) 46 if(parent[x1]>parent[y1]) 47 { 48 parent[x1]=y1; 49 parent[y1]=temp; 50 } 51 else 52 { 53 parent[y1]=x1; 54 parent[x1]=temp; 55 } 56 } 57 int comp(const void *a,const void *b) 58 { 59 return (*(struct node *)a).w-(*(struct node *)b).w; 60 } 61 int kruskal() 62 { 63 init(); 64 int sum=0,num=0; 65 int u,v; 66 for(int i=0;i<m;i++) 67 { 68 if(edge[i].del==1) 69 continue; 70 u=edge[i].u; 71 v=edge[i].v; 72 if(find(u)!=find(v)) 73 { 74 sum+=edge[i].w; 75 num++; 76 merge(u,v); 77 if(first) 78 edge[i].used=1; 79 } 80 if(num>=n-1) 81 break; 82 } 83 return sum; 84 } 85 int main() 86 { 87 int u,v,w; 88 int t,i,j,k; 89 scanf("%d",&t); 90 while(t--) 91 { 92 scanf("%d%d",&n,&m); 93 for(j=0;j<m;j++) 94 { 95 scanf("%d%d%d",&u,&v,&w); 96 edge[j].u=u-1; 97 edge[j].v=v-1; 98 edge[j].w=w; 99 edge[j].equal=edge[j].del=edge[j].used=0; 100 } 101 for(i=0;i<m;i++) 102 { 103 for(j=0;j<m;j++) 104 { 105 if(i==j) 106 continue; 107 if(edge[i].w==edge[j].w) 108 { 109 edge[i].equal=1; 110 } 111 } 112 } 113 114 qsort(edge,m,sizeof(edge[0]),comp); 115 first=true; 116 int w1=kruskal(); 117 first=false; 118 for(j=0;j<m;j++) 119 { 120 if(edge[j].used&&edge[j].equal) 121 { 122 edge[j].del=1; 123 int w2=kruskal(); 124 if(w1==w2) 125 { 126 puts("Not Unique!"); 127 break; 128 } 129 edge[j].del=0; 130 } 131 } 132 if(j>=m) 133 printf("%d\n",w1); 134 } 135 return 0; 136 }