码迷,mamicode.com
首页 > 其他好文 > 详细

POJ3723(邻接表+并查集+Kruskal)

时间:2015-03-28 14:24:45      阅读:109      评论:0      收藏:0      [点我收藏+]

标签:kruskal

题目链接:点击打开链接


解题思路:

根据相互之间的关系,可以转化一个无向图中最大权森林的问题。也就是把边权取反,然后用最小生成树求解。

本题用邻接表存储,Kruskal求最小生成树。


完整代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <set>
#include <vector>
#include <climits>
#include <queue>
using namespace std;
typedef long long LL;
const int maxn = 500001;

struct edge
{
    int u , v , cost;
};

int n , m , r;
int x[maxn] , y[maxn] , d[maxn];


bool cmp(const edge &e1 , const edge &e2)
{
    return e1.cost < e2.cost;
}

edge es[maxn];
int V , E;

int f[maxn] , rank[maxn];

void init_union_find(int cnt)
{
    for(int i = 0 ; i <= cnt ; i ++)
    {
        f[i] = i;
        rank[i] = 0;
    }
}

int find(int key)
{
    return f[key] = f[key] == key ? key : find(f[key]);
}

void unite(int x , int y)
{
    x = find(x);
    y = find(y);
    if(x != y)
    {
        if(rank[x] < rank[y])
        {
            f[x] = y;
        }
        else
        {
            f[y] = x;
            if(rank[x] == rank[y])
                rank[x] ++;
        }
    }
}


bool same(int x , int y)
{
    return find(x) == find(y);
}



int kruskal()
{
    sort(es , es + E , cmp);
    init_union_find(V);
    int res = 0;
    for(int i = 0 ; i < E ; i ++)
    {
        edge e = es[i];
        if(!same(e.u , e.v))
        {
            unite(e.u , e.v);
            res += e.cost;
        }
    }
    return res;
}

void solve()
{
    V = n + m;
    E = r;
    for(int i = 0 ; i < r ; i ++)
    {
        es[i] = (edge){ x[i] , n + y[i] , -d[i] };
    }
    LL res = 10000 * (n + m) + kruskal();
    printf("%lld\n" , res);
}

int main()
{

    #ifdef DoubleQ
    freopen("in.txt" , "r" , stdin);
    #endif
    int T;
    cin >> T;
    while(T--)
    {
        //cin >> n >> m >> r;
        scanf("%d%d%d" , &n , &m , &r);
        for(int i = 0 ; i < r ; i ++)
        {
            //cin >> x[i] >> y[i] >> d[i];
            scanf("%d%d%d" , &x[i] , &y[i] , &d[i]);
        }
        solve();
    }
    return 0;
}

更多精彩请访问:点击打开链接

POJ3723(邻接表+并查集+Kruskal)

标签:kruskal

原文地址:http://blog.csdn.net/u013447865/article/details/44700691

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!