按照点最小输出 最小生成树的边
。。。加等号才过是什么鬼
#include <bits/stdc++.h>
using namespace std;
const int MAXN=111;
#define typec int
const typec INF=0x3f3f3f3f;//防止后面溢出,这个不能太大
int mp[MAXN][MAXN],dis[MAXN];
int flag[MAXN],n,tol;
struct node
{
int a,b;
}pre[MAXN],out[MAXN];
int prim()
{
int i,min_i,j;
int Min;
int ans=0;
for(i=1 ; i <=n ; i++ )
{
dis[i] = mp[i][1];
pre[i].a=1;
pre[i].b=i;
}
memset( flag, 0, sizeof(flag));
flag[1] = 1;
for(i=2 ; i <=n ; i++ )
{
Min = INF;
min_i=i;
for( j=2 ; j <=n ; j++ )
{
if(flag[j]==0 && dis[j]<=Min)//加等号才过什么鬼
{
Min=dis[j];
min_i=j;
}
}
if(Min==INF)
break;
ans+=Min;
out[tol++]=pre[min_i];
flag[min_i] = 1;
for( j=2 ; j <=n ; j++ )
{
if(mp[min_i][j]==INF) continue;
if(flag[j]==0 && dis[j]==mp[min_i][j])
{
pre[j].a=min(pre[j].a,min_i);
}
if(flag[j]==0 && dis[j]>mp[min_i][j])
{
dis[j] = mp[j][min_i];
pre[j].a=min_i;
}
}
}
if(i==n+1)
return ans;
else return -1;
}
bool cmp(node x,node y)
{
if(x.a==y.a) return x.b<y.b;
return x.a<y.a;
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&mp[i][j]);
if(mp[i][j]==0) mp[i][j]=INF;
}
}
tol=0;
if(prim()==-1)
{
printf("-1\n");
continue;
}
for(int i=0;i<tol;i++)
{
if(out[i].a>out[i].b)
{
int temp=out[i].a;
out[i].a=out[i].b;
out[i].b=temp;
}
}
sort(out,out+tol,cmp);
for(int i=0;i<tol;i++)
{
if(i)
printf(" ");
printf("%d %d",out[i].a,out[i].b);
}
printf("\n");
}
return 0;
}
/*
4
4
0 3 5 7
3 0 2 1
5 2 0 3
7 1 3 0
3
0 2 0
2 0 0
0 0 0
2
0 2
2 0
*/