从算法来说是很简单题,这题主要是控制输出。用KRUSKAL算法时,如果遇到多条相同长度的边就排列点。看我的 ' < ' 重载就行,对输出也要排。看qsort ( )。
这题WA得让人惊心动魄啊!
#include <iostream>
#include <cstring>
#include <queue>
#include <cstdlib>
#include <cstdio>
using namespace std;
struct vertex
{
int val;
int u;
int v;
};
struct Mtree
{
int l;
int r;
}tree[200];
priority_queue<vertex> q;
int cmp(const void* a,const void* b)
{
if((*(Mtree*)a).l != (*(Mtree*)b).l)
return (*(Mtree*)a).l - (*(Mtree*)b).l;
else
return (*(Mtree*)a).r - (*(Mtree*)b).r;
}
bool operator< (const vertex &a,const vertex &b)
{
if(a.val != b.val){
if(a.val > b.val)return 1;
else return 0;}
else
{
if(a.u != b.u){
if(a.u > b.u) return 1;
else return 0;}
else{
if(a.v>b.v) return 1;
else return 0;
}
}
}
int id[101],sz[101],k;
bool cnet(int p,int q)
{
int i,j;
for(i = p;i != id[i];i = id[i]);
for(j = q;j != id[j];j = id[j]);
if(i == j) return 0;
if(sz[i] < sz[j])
{
id[i] = j;sz[j] += sz[i];
}
else
{
id[j] = i;sz[i] += sz[j];
}
return 1;
}
void kru()
{
while(!q.empty())
{
if(cnet(q.top().u,q.top().v) == 1)
{
tree[k].l = q.top().u;
tree[k].r = q.top().v;
k ++;
}
q.pop();
}
}
int main()
{
int i,w,cas,n,j;
vertex tmp;
scanf("%d",&cas);
while(cas --)
{
for(i = 0;i < 101;i ++) {id[i] = i;sz[i] = i;}
scanf("%d",&n);
for(i = 1;i <= n;i ++)
for(j = 1;j <= n;j ++)
{
scanf("%d",&w);
if(j > i&&w != 0){
tmp.val = w;
tmp.u = i;
tmp.v = j;
q.push(tmp);
}
}
k = 0;
kru();
qsort(tree,k,sizeof(tree[0]),cmp);
if(k != n - 1) printf("-1\n");
else{
printf("%d %d",tree[0].l,tree[0].r);
for(i = 1;i < k;i ++)
{
printf(" %d %d",tree[i].l,tree[i].r);
}
printf("\n");
}
while(!q.empty()) q.pop();
}
return 0;
}