您的位置:首页 > 产品设计 > UI/UE

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

2012-10-04 11:13 866 查看
思路:

(1)对图中每条边,扫描其他边,如果存在相同权值的边,则对该边做标记。

(2)然后用Kruskal求MST。

(3)求得MST后,如果该MST中未包含做了标记的边,即可判定MST唯一,如果包含了做了标记的边,则依次去掉这些再求MST,如果求的MST权值和原MST权值相同,即可判定MST不唯一。

代码:

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
using namespace std;
const int maxn=101;
const int maxm=10001;
struct node
{
int u;
int v;
int w;
int equal;
int used;
int del;
}edge[maxm];
int parent[maxn];
int n,m;
bool first;
void init()
{
for(int i=0;i<=n;i++)
{
parent[i]=-1;
}
}
int find(int x)
{
int s;
for(s=x;parent[s]>=0;s=parent[s]);
while(s!=x)
{
int temp=parent[x];
parent[x]=s;
x=temp;
}
return s;
}
void merge(int x,int y)
{
int x1=find(x);
int y1=find(y);
int temp=parent[x1]+parent[y1];//两个集合节点个数之和(<0)
if(parent[x1]>parent[y1])
{
parent[x1]=y1;
parent[y1]=temp;
}
else
{
parent[y1]=x1;
parent[x1]=temp;
}
}
int comp(const void *a,const void *b)
{
return (*(struct node *)a).w-(*(struct node *)b).w;
}
int kruskal()
{
init();
int sum=0,num=0;
int u,v;
for(int i=0;i<m;i++)
{
if(edge[i].del==1)
continue;
u=edge[i].u;
v=edge[i].v;
if(find(u)!=find(v))
{
sum+=edge[i].w;
num++;
merge(u,v);
if(first)
edge[i].used=1;
}
if(num>=n-1)
break;
}
return sum;
}
int main()
{
int u,v,w;
int t,i,j,k;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(j=0;j<m;j++)
{
scanf("%d%d%d",&u,&v,&w);
edge[j].u=u-1;
edge[j].v=v-1;
edge[j].w=w;
edge[j].equal=edge[j].del=edge[j].used=0;
}
for(i=0;i<m;i++)
{
for(j=0;j<m;j++)
{
if(i==j)
continue;
if(edge[i].w==edge[j].w)
{
edge[i].equal=1;
}
}
}

qsort(edge,m,sizeof(edge[0]),comp);
first=true;
int w1=kruskal();
first=false;
for(j=0;j<m;j++)
{
if(edge[j].used&&edge[j].equal)
{
edge[j].del=1;
int w2=kruskal();
if(w1==w2)
{
puts("Not Unique!");
break;
}
edge[j].del=0;
}
}
if(j>=m)
printf("%d\n",w1);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: