题目:http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=3204
题意:求一课最小生成树,但要按照字典序把路径打印出来
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=10005;
struct node
{
int a,b;
}e[maxn];
int n,p[105],r[maxn],u[maxn],v[maxn],w[maxn],m,cnt;
int cmp(const int i,const int j)
{
if(w[i]!=w[j]) return w[i]<w[j];
else
{
if(u[i]!=u[j]) return u[i]<u[j];//这里也要排序,怪自己不小心
else return v[i]<v[j];
}
}
int Find(int x) {return x==p[x]?x:p[x]=Find(p[x]);}
void kru()
{
cnt=0;
for(int i=0;i<=n;i++)
p[i]=i;
for(int i=0;i<=m;i++)
r[i]=i;
sort(r,r+m,cmp);
for(int i=0;i<m;i++)
{
int q=r[i];
int x=Find(u[q]),y=Find(v[q]);
if(x!=y&&w[q]!=0)
{
p[x]=y;
if(u[q]<v[q])
{e[cnt].a=u[q];e[cnt++].b=v[q];}
else
{
e[cnt].b=u[q];e[cnt++].a=v[q];
}
}
}
}
bool cmp1(const node &a,const node &b)
{
if(a.a!=b.a) return a.a<b.a;
else return a.b<b.b;
}
int main(void)
{
int t,x;
scanf("%d",&t);
while(t--)
{
m = 0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&x);
if(i < j)
{
u[m]=i,v[m]=j,w[m++]=x;
}
}
}
kru();
int k=Find(1);
bool flag=true;
for(int i=1;i<=n;i++)
{
int d=Find(i);
if(d!=k) {flag=false;break;}
}
if(!flag) printf("-1\n");
else
{
sort(e,e+cnt,cmp1);
for(int i=0;i<cnt;i++)
{
if(i!=cnt-1)
printf("%d %d ",e[i].a,e[i].b);
else printf("%d %d",e[i].a,e[i].b);
}
printf("\n");
}
}
return 0;
}