题意:给你N台电脑,让你把它们全部连在一起,当把两个电脑连在一起时,有一定的花费,问你最小的花费是多少?
注意:i和j相连同j和i相连是一样的,可以间接的连在一起,例如:i和j相连,j和t相连,那么i和t也相连。
按照字典序输出,利用qsort()排序。然后判断连通度即可。
#include<iostream>
#include<algorithm>
#include<cstdio>
#define max 110
using namespace std;
int t,T;
struct node
{
int x;
int y;
int r;
} Node[max*max],out[max];
int pre[max];
int s;
void init()
{
int tem;
s=0;
for(int j=1; j<=t; j++)
for(int i=1; i<=t; i++)
{
scanf("%d",&tem);
if(i<=j)
continue;
if(tem==0)
continue;
Node[s].x=j;
Node[s].y=i;
Node[s].r=tem;
s++;
}
}
int cmp1(const void *a,const void *b)//i到j等于j到i
{
node aa=*(node *)a;
node bb=*(node *)b;
if(aa.r!=bb.r)
return aa.r-bb.r;
else if(aa.x!=bb.x)
return aa.x-bb.x;//从小到大排
return aa.y-bb.y;//从小到大排
}
int cmp2(const void *a,const void *b)//从小到大排序
{
node aa=*(node *)a;
node bb=*(node *)b;
if(aa.x!=bb.x)
return aa.x-bb.x;
return aa.y-bb.y;
}
int find(int x)
{
while(x!=pre[x])
x=pre[x];
return x;
}
void kruskal()
{
int a,b,count=0;
qsort(Node,s,sizeof(Node[0]),cmp1);
for(int i=1; i<=t; i++)
pre[i]=i;
for(int i=0; i<s; i++)
{
a=find(Node[i].x);
b=find(Node[i].y);
if(a!=b)
{
pre[b]=a;
out[count++]=Node[i];
}
}
// printf("count=%d t=%d\n",count,t);
if(count==t-1)
{
qsort(out,count,sizeof(out[0]),cmp2);
printf("%d %d",out[0].x,out[0].y);
for(int i=1; i<count; i++)
printf(" %d %d",out[i].x,out[i].y);
printf("\n");
}
else
{
printf("-1\n");
}
}
int main()
{
while(scanf("%d",&T)!=EOF)
{
while(T--)
{
scanf("%d",&t);
init();
kruskal();
}
}
return 0;
}