ZOJ Problem Set - 3204 Connect them

从算法来说是很简单题,这题主要是控制输出。用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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值