求助!! 唯一的最小生成树
Description
求一个非负权边的无向连通图的最小生成树,如果这个无向图存在两个或两个以上的最小生成树,就输出Not Unique,否则输出最小生成树的边的权值和。
输入:
第一行是一个整数K,表示有多少个测试用例,以后每个测试用例占m+1行。每个测试用例的第一行为两个整数n,m(3<=n<=100),表示图的顶点数和边数,从第二行开始每行为三个整数i,j,w,表示从i到j顶点的权值。
输出:
每行输出一个测试用例的结果。如果这个无向图存在两个或两个以上的最小生成树,就输出Not Unique,否则输出最小生成树的边的权值和。
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
我的代码是
#include<stdio.h>
#include<string.h>
//#include<malloc.h>
#include<stdlib.h>
#define MAX 110
#define Infinity 100000
int MinSpanTree_Prim(int d[][MAX],int n)
{
bool Visited[MAX],T1[MAX][MAX],T2[MAX][MAX];
int Closest[MAX],Lowcost[MAX],g;
int root,i,j,k,min;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
T1[i][j]=false;
T2[i][j]=false;
}
for(root=1;root<=n;root++)
{
if(root>1)
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
T2[i][j]=false;
}
for(i=1;i<=n;i++)
{
Visited[i]=false;
if(i!=root)
{
Lowcost[i]=d[root][i];
Closest[i]=root;
}
}
Visited[root]=true;
g=0;
for(k=0;k<=n-2;k++)
{
min=Infinity;
for(i=1;i<=n;i++)
{
if((i!=root)&&(!Visited[i])&&(Lowcost[i]<min))
{
min=Lowcost[i];
j=i;
}
}
Visited[j]=true;
if(root==1) //生成的第一个最小生成树放在T1里
{
T1[j][Closest[j]]=true;
T1[Closest[j]][j]=true;
}
else //其余的每次放在T2里用来跟T1比较
{
T2[j][Closest[j]]=true;
T2[Closest[j]][j]=true;
}
g+=min;
for(i=1;i<=n;i++)
if((i!=root)&&(!Visited[i])&&(d[j][i]<Lowcost[i]))
{
Lowcost[i]=d[j][i];
Closest[i]=j;
}
}
if(root>1) //以下用来判断有没有重复的生成树
{
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
if(T1[i][j]!=T2[i][j]) //如果生成树唯一 ,则每次得 return -1; //的邻接矩阵都完全相同 否则返回-1
}
}
}
return g;
}
void main()
{
int i,j,k,Case,n,m,x,y,z,result;
int d[MAX][MAX];
scanf("%d",&Case);
while(Case--)
{
for(i=0;i<MAX;i++)
for(j=0;j<MAX;j++)
d[i][j]=Infinity;//千万别初始化成0
scanf("%d %d",&n,&m);
for(i=1;i<=m;i++)
{
scanf("%d %d %d",&x,&y,&z);
d[x][y]=z;
d[y][x]=z;
}
result=MinSpanTree_Prim(d,n);
if(result==-1)
printf("Not Unique\n");
else
printf("%d\n",result);
}
getchar();
}
我的方法是用PRIM算法求得每一个最小生成树(从每个根节点开始) 如果只有唯一的 则每一个最小生成树的邻接矩阵都一定完全相同吧?
测试用例通过了 自己的例子也通过了 但是一直WRONG ANWSER 求陷阱数据