ZOJ 3204 最小生成树prim和kruskal综合版

#include<iostream>
#include<string>
#include<cstring>
#include<vector>
#include<utility>
#include<bits/stdc++.h>
using namespace std;

#define MAXSIZE 120
int n,i,j,k,mini;
const int maxn = 99999;

int c[MAXSIZE][MAXSIZE];
int parent[MAXSIZE];

struct cmp
{
    bool operator()( pair<int,int> a, pair<int,int> b )
    {
        if(a.first == b.first)
            return a.second > b.second;
        else
            return a.first > b.first;
    }
};


struct edge{
    int a, b;
    int weight;
    bool operator < (const edge &q) const{
        if(weight == q.weight)
        {
            if(a == q.a)
            {
                return b > q.b;
            }
            return a > q.a;
        }
        return weight > q.weight;
    }
}a;

struct ansedge{
    int a, b;
    bool operator < (const ansedge &q) const{
            if(a == q.a)
            {
                return b > q.b;
            }
            return a > q.a;
    }
}e;

int Find(int x)
{
    int r = x;
    while(parent[r] != r)
        r = parent[r];
    i = x;
    while(i != r)
    {
        j = parent[i];
        parent[i] = r;
        i = j;
    }
    return r;
}
void uion(int x ,int y)
{
    int r = Find(x);
    int h = Find(y);
    if(r < h)
        parent[h] = r;
    else
        parent[r] = h;
}

void prim()
{
    memset(c,0,sizeof(c));
    cin >> n;
    for(i = 1; i <= n; i++)
    {
        for(j = 1; j <= n; j++)
        {
            cin >> c[i][j];
            if(c[i][j] == 0)
                c[i][j] = maxn;
        }
    }
    int Vis[MAXSIZE],Lowcost[MAXSIZE],prenode[MAXSIZE];
    memset(Vis, 0, sizeof(Vis));
    memset(Lowcost, 0, sizeof(Lowcost));
    priority_queue<pair<int,int>,vector< pair<int,int> >, cmp> E;
    Vis[1] = 1;
    for(i = 2; i <= n; i++)
    {
        Lowcost[i] = c[1][i];
        prenode[i] = 1;
    }
    int node_num = 1,pos2;
    for(int k = 2; k <= n; k++)
    {
        mini = maxn;
        for(j = 1; j <= n; j++)
        {
            if(!Vis[j] && mini >= Lowcost[j] && Lowcost[j] < maxn)
            {
                mini = Lowcost[j];
                pos2 = j;
//                   cout << mini << endl;
            }
        }
        if(mini == maxn)
        {
            break;
        }
        if(prenode[pos2] <pos2)
        {
            E.push(make_pair(prenode[pos2],pos2));
        }
        else
        {
            E.push(make_pair(pos2, prenode[pos2]));
        }
        Vis[pos2] = 1;
        for(j = 1; j <= n; j++)
        {
            if(!Vis[j] && c[pos2][j] < Lowcost[j])
            {
                Lowcost[j] = c[pos2][j];
                prenode[j] = pos2;
            }
            if(!Vis[j] && c[pos2][j] == Lowcost[j] && pos2 < prenode[j])
            {
                prenode[j] = pos2;
            }
        }
        node_num++;
    }
    int flag = 1;
    if(node_num == n)
    {
        while(!E.empty())
        {
            if(flag)
            {
                cout << E.top().first << ' ' << E.top().second;
                flag = 0;
                E.pop();
            }
            else
            {
                cout <<' ' << E.top().first << ' ' << E.top().second;
                E.pop();
            }
        }
        cout << endl;
    }
    else
    {
        cout << -1 << endl;
    }
}

void kruskal()
{
     for(i = 0; i < MAXSIZE; i++)
    {
        parent[i] = i;
    }
    priority_queue<edge> E;
    priority_queue<ansedge> ans;
    memset(c,0,sizeof(c));
    cin >> n;

    for(i = 1; i <= n; i++)
    {
        for(j = 1; j <= n; j++)
        {
            cin >> c[i][j];
            if(j <= i)
                continue;
            if(c[i][j] == 0)
                continue;
            a.a = i;
            a.b = j;
            a.weight = c[i][j];
            E.push(a);
        }
    }

    while(!E.empty())
    {
        if(Find(E.top().a) == Find(E.top().b))
        {
            E.pop();
        }
        else if(Find(E.top().a) != Find(E.top().b))
        {
            uion(E.top().b,E.top().a);
            e.a = E.top().a;
            e.b = E.top().b;
            ans.push(e);
            E.pop();
        }
   //     */
    }
    int flag = 1;
    if(ans.size() != n-1)
    {
        cout << -1 << endl;
        return;
    }
    while(!ans.empty())
    {
        if(flag)
        {
            cout <<ans.top().a << ' ' << ans.top().b;
            ans.pop();
            flag = 0;
        }
        else
        {
            cout <<' '<< ans.top().a << ' ' << ans.top().b ;
            ans.pop();
        }
    }
    cout << endl;
}
int main()
{
    int T;
    cin >> T;
    while(T--)
    {
       kruskal();
    //   prim();
    }
    return 0;
}
/*
1
10
0 1 2 3 4 5 6 7 8 9
1 0 3 2 3 4 5 6 7 8
2 3 0 1 2 3 4 5 6 7
3 2 1 0 1 2 3 4 5 6
4 3 2 1 0 1 2 3 4 5
5 4 3 2 1 0 1 2 3 4
6 5 4 3 2 1 0 1 2 3
7 6 5 4 3 2 1 0 1 2
8 7 6 5 4 3 2 1 0 1
9 8 7 6 5 4 3 2 1 0
1 2 2 4 3 4 4 5 5 6 6 7 7 8 8 9 9 10
1 2 1 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10
1
3
0 2 7
2 0 5
7 5 0

1
4
0 4 3 2
4 0 2 1
3 2 0 1
2 1 1 0

*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值