POJ3723(鄰接表+並查集+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;
}

更多精彩請訪問:點擊打開鏈接
發佈了403 篇原創文章 · 獲贊 20 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章