POJ 1679 The Unique MST(判断最小生成树是否唯一)

思路:

(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 }

 

原文地址:https://www.cnblogs.com/pony1993/p/2711352.html