雕刻时光

just do it……nothing impossible
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

最小生成树唯一性检验——PKU1679

Posted on 2011-02-16 22:33  huhuuu  阅读(555)  评论(0编辑  收藏  举报
正反两次遍历最小生成树,把结果顶点的连通性结果分别放在hash[][],hash2[][]里,在比较若相同,则树唯一,反之不唯一
View Code
#include<stdio.h>

#define MAX 0x3fffffff
int map[102][102];
bool use[102];
bool hash[102][102];
bool hash2[102][102];

int main()
{
int n,i,j,k,t,a,b,m;
scanf(
"%d",&t);
while(t--)
{
scanf(
"%d%d",&n,&m);
{
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
map[i][j]
=MAX;
hash[i][j]
=0;
hash2[i][j]
=0;
}
use[i]
=0;
}
for(i=1;i<=m;i++)
{
scanf(
"%d%d",&a,&b);
scanf(
"%d",&map[a][b]);
map[b][a]
=map[a][b];
}

int add=0,ri,rj,min;
use[
1]=1;
for(k=1;k<n;k++)
{
min
=MAX;
rj
=1;
for(i=1;i<=n;i++)
{
if(use[i]==0) continue;
for(j=1;j<=n;j++)
{
if((i!=j)&&use[j]==0&&map[i][j]<min)
{
min
=map[i][j];
ri
=i;
rj
=j;
}
}
}
add
+=min;
use[rj]
=1;
hash[ri][rj]
=1;
hash[rj][ri]
=1;
}

for(i=1;i<=n;i++)
use[i]
=0;//不要忘了用过的use初始化
use[1]=1;
for(k=1;k<n;k++)
{
min
=MAX;
rj
=1;
for(i=n;i>=1;i--)
{
if(use[i]==0) continue;
for(j=n;j>=1;j--)
{
if((i!=j)&&use[j]==0&&map[i][j]<min)
{
min
=map[i][j];
ri
=i;
rj
=j;
}
}
}
use[rj]
=1;
hash2[ri][rj]
=1;
hash2[rj][ri]
=1;
}

bool rt=0;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(hash[i][j]!=hash2[i][j])
{
printf(
"Not Unique!\n");
rt
=1;
break;
}
}
if(rt==1)
break;
}
if(rt==0)
printf(
"%d\n",add);
}
}
}