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 }

 

 

你可能感兴趣的:(unique)