标签:des style http color os io for cti
Description
Input
Output
Sample Input
2 3 3 1 2 1 2 3 2 3 1 3 4 4 1 2 2 2 3 2 3 4 2 4 1 2
Sample Output
3 Not Unique!
Source
题意:就是判断最小生成树是不是唯一的,换而言之就是最小生成树的一条边能不能被别的边代替
思路:先来一遍最小生成树,把加入最小生成树的边标记,然后一一去掉这条边,看看有没有边能代替这条边,也就是看最小生成树的值变不变
就说这么多了,应该清楚了吧,看代码吧
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 10005
struct stud{
int a,b,len;
}f[N];
int father[N],vis[N],n,m;
int sum;
int cmp(stud a,stud b)
{
return a.len<b.len;
}
int cha(int x)
{
if(x!=father[x])
father[x]=cha(father[x]);
return father[x];
}
int fdd(int x)
{
int i;
for(i=0;i<=n;i++)
father[i]=i;
int num=1,ans=0;
for(i=0;i<m;i++)
{
if(i==x) continue; //该标记的边不加入生成树
int aa=cha(f[i].a);
int bb=cha(f[i].b);
if(aa!=bb)
{
father[aa]=bb;
num++;
ans+=f[i].len;
if(num==n)
break;
}
}
if(num==n&&ans==sum) return 1; //记住必须是两个条件,缺一不可
return 0;
}
int main()
{
int t,i;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(i=0;i<m;i++)
scanf("%d%d%d",&f[i].a,&f[i].b,&f[i].len);
for(i=0;i<=n;i++)
father[i]=i;
sort(f,f+m,cmp); //按边排序
int num=1;
memset(vis,0,sizeof(vis));
sum=0;
for(i=0;i<m;i++)
{
int aa=cha(f[i].a);
int bb=cha(f[i].b);
if(aa!=bb)
{
father[aa]=bb;
num++;
vis[i]=1; //标记加入生成树的边
sum+=f[i].len; //最小生成树的值为sum
if(num==n) break; //n个点,需要n-1条边(num初始值为1)
}
}
int flag=0;
for(i=0;i<m;i++)
if(vis[i]) //如果这条边加入到生成树,就看看有么有边能代替他
if(fdd(i)) //如果能 break;
break;
if(i!=m)
printf("Not Unique!\n");
else
printf("%d\n",sum);
}
return 0;
}
POJ 1679 The Unique MST,布布扣,bubuko.com
标签:des style http color os io for cti
原文地址:http://blog.csdn.net/u014737310/article/details/38355579