整理下昨晚写的题。。wa了数次。。
/*
zoj_3204 最小生成树
kruskal写的,最让我纠结的是priority_queue和vector一起出现而且两个都要重载过比较函数。。
写错了数次。。特别是priority_queue对<的重载,特别注意啊。。
注意:在选边时有多条相同长度路径,所有选择的时候要序号排前的优先。
输出的时候也是。
*/
#include <iostream>
#include <queue>
#include <cstdio>
#include <algorithm>
using namespace std;
struct computer
{
int from,to,value;
};
computer co[110];
vector <computer>v;
int father[110],cou;
priority_queue <computer> p;
bool operator<( const computer &a,const computer &b )
{
if( a.value!=b.value ) return a.value>b.value;
if( a.from!=b.from ) return a.from>b.from;
return a.to>b.to;
}
/*重载方法二
struct cmp
{
bool operator()(computer a,computer b )
{
if( a.value!=b.value ) return a.value>b.value;
if( a.from!=b.from ) return a.from>b.from;
return a.to>b.to;
}
};
priority_queue <computer,vector<computer>,cmp > p;
*/
bool cmp2(computer a,computer b )
{
if( a.from!=b.from ) return a.from<b.from;
return a.to<b.to;
}
int find_set( int a )
{
if( a!=father[a] )
{
father[a]=find_set( father[a] );
}
return father[a];
}
void union_set( int a,int b )
{
int x,y;
x=find_set(a);
y=find_set(b);
if( x==y ) return;
father[y]=x;
computer temp;
temp.from=a;
temp.to=b;
temp.value=0;
cou++;
v.push_back( temp );
}
int main()
{
int T,n,i,j;
computer temp;
scanf( "%d",&T );
while( T-- )
{
for( i=0;i<110;i++ )
father[i]=i;
scanf( "%d",&n );
for( i=1;i<=n;i++ )
{
for( j=1;j<=n;j++ )
{
scanf( "%d",&temp.value );
if( j<=i ) continue;
if( temp.value )
{
temp.from=i;
temp.to=j;
p.push( temp );
}
}
}
cou=0;
while( !p.empty() )
{
temp=p.top(); p.pop();
// cout<<temp.from<<" "<<temp.to<<endl;
union_set( temp.from,temp.to );
}
if( cou!=n-1 )
printf("-1\n");
else
{
sort( v.begin(),v.end(),cmp2 );
printf( "%d %d",v[0].from,v[0].to );
for( i=1;i<v.size();i++ )
printf( " %d %d",v[i].from,v[i].to );
printf("\n");
}
v.clear();
}
return 0;
}