题意:输出字母序最小的最小生成树
思路:对边按照cost u v排序之后,求最小生成树,然后在对u v排序输出
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <cmath>
#include <cctype>
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 10005;
struct node{
int u,v;
int cost;
}no[maxn];
struct node1{
int u,v;
}ans[maxn];
bool cmp2(struct node1 a,struct node1 b){
if(a.u == b.u){
return a.v < b.v;
}
return a.u < b.u;
}
int pre[105];
int find(int x){
if(x == pre[x]){
return x;
}
else{
return pre[x] = find(pre[x]);
}
}
bool join(int x,int y){
int fx = find(x);
int fy = find(y);
if(fx != fy){
pre[fy] = fx;
return 1;
}
return 0;
}
bool cmp1(struct node a,struct node b){
if(a.cost == b.cost){
if(a.u == b.u){
return a.v < b.v;
}
return a.u < b.u;
}
return a.cost < b.cost;
}
int main(void){
int t;
scanf("%d",&t);
while(t--){
int n;
scanf("%d",&n);
int cnt = 0;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
int co;
scanf("%d",&co);
if(i < j && co != 0){
no[cnt].u = i;
no[cnt].v = j;
no[cnt].cost = co;
cnt++;
}
}
}
sort(no,no + cnt,cmp1);
for(int i = 1; i <= n; i++){
pre[i] = i;
}
int cntt = 0;
int pos;
for(int i = 0; i < cnt; i++){
if(join(no[i].u,no[i].v)){
struct node1 temp;
temp.u = no[i].u;
temp.v = no[i].v;
ans[cntt++] = temp;
}
if(cntt == n - 1){
pos = i;
break;
}
}
if(cntt == n - 1){
sort(ans,ans + n - 1,cmp2);
for(int i = 0; i < n - 1; i++){
if(i == n - 2){
printf("%d %d\n",ans[i].u,ans[i].v);
}
else{
printf("%d %d ",ans[i].u,ans[i].v);
}
}
}
else{
printf("-1\n");
}
}
return 0;
}