//zoj3204||poj3450 最小生成树,要求字典序最小的先输出
//需要输出边的顶点的一类题用prim不会啊,请大神指点一下
//还要注意输出行末尾不能有空格
#include"stdio.h"
#include"stdlib.h"
#include"limits.h"
#define N 102
typedef struct side
{
int e,s,len;
}side;
side sides[N*N];
int n,cases,g[N][N],has[N*N];
int input()
{
int i,j,k;
scanf("%d",&n);
for(i=1;i<=n;i++)
for(k=1;k<=n;k++)
{
scanf("%d",&g[i][k]);
if(g[i][k]==0)
g[i][k]=INT_MAX;
}
for(i=1,j=0;i<n;i++)
for(k=i+1;k<=n;k++)
{
sides[j].s=i;
sides[j].e=k;
sides[j].len=g[i][k];
j++;
}
return j;
}
int cmp(const void *a,const void *b)
{
side *a1,*b1;
a1=(side*)a;
b1=(side*)b;
if(a1->len>b1->len)
return 1;
if(a1->len<b1->len)
return -1;
if(a1->s>b1->s)
return 1;
if(a1->s<b1->s)
return -1;
if(a1->e>b1->e)
return 1;
else
return -1;
}
int cmp2(const void *a,const void *b)
{
side aa = *(side*)a;
side bb = *(side*)b;
if( aa.s != bb.s) return aa.s-bb.s;
else return aa.e-bb.e;
}
int find(int i)
{
while(has[i]!=i)
i=has[i];
return i;
}
void kruscal(int p)
{
int i,j=0,v1,v2;
side tree[N];
for(i=0;i<=p;i++)
has[i]=i;
qsort(sides,p,sizeof(side),cmp);
for(i=0;i<p;i++)
{
if(sides[i].len==INT_MAX)
break;
v1=find(sides[i].s);
v2=find(sides[i].e);
if(v1!=v2)
{
tree[j]=sides[i];
has[v1]=v2;
j++;
if(j==n-1)
break;
}
}
if(j==n-1)
{
qsort(tree,j,sizeof(side),cmp2);
for(i=0;i<j;i++)
{
printf("%d %d",tree[i].s,tree[i].e);
if(i!=j-1)
printf(" ");
}
}
else
printf("-1");
}
int main ()
{
scanf("%d",&cases);
while(cases--)
{
kruscal(input());
if(cases)
printf("\n");
}
return 0;
}zoj3204||poj3450 最小生成树
最新推荐文章于 2025-11-19 18:47:04 发布
本文深入探讨了最小生成树的概念,并详细解释了Prim算法在寻找字典序最小的边集过程中的应用。文章通过实例展示了如何使用Prim算法解决实际问题,包括输入数据的读取、边的存储与排序、以及最终输出结果的处理,特别强调了输出格式的规范性。


3333

被折叠的 条评论
为什么被折叠?



