正反两次遍历最小生成树,把结果顶点的连通性结果分别放在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);
}
}
}