hdoj 1233 还是畅通工程(最小生成树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1233

思路分析:该问题为最小生成树问题,使用kruskal算法或者prim算法即可解决;

代码如下:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const int MAX_N = 5000 + 10;
int u[MAX_N], v[MAX_N], w[MAX_N];
int p[MAX_N], r[MAX_N];

inline int cmp(const int i, const int j) { return w[i] < w[j]; }
int Find(int a)
{
    if (p[a] == a)
        return a;
    else
        return p[a] = Find(p[a]);
}

int Union(int a, int b)
{
    int p_a = Find(a);
    int p_b = Find(b);

    if (p_a == p_b)
        return -1;
    if (p_a > p_b)
        p[p_b] = p_a;
    else
        p[p_a] = p_b;
    return 1;
}

inline int Kruskal(int road_num)
{
    int ans = 0;

    for (int i = 0; i <= road_num; ++i)
        p[i] = i;
    for (int i = 0; i < road_num; ++i)
        r[i] = i;
    sort(r, r + road_num, cmp);
    for (int i = 0; i < road_num; ++i)
    {
        int e = r[i];
        int x = Find(u[e]);
        int y = Find(v[e]);
        if (x != y)
        {
            ans += w[e];
            Union(x, y);
        }
    }
    return ans;
}

int main()
{
    int ver_num;
    int ver_1, ver_2, len;

    while (scanf("%d", &ver_num) != EOF && ver_num)
    {
        int road_num = ver_num * (ver_num - 1) / 2;
        for (int i = 0; i < road_num; ++i)
        {
            scanf("%d %d %d", &ver_1, &ver_2, &len);
            u[i] = ver_1;
            v[i] = ver_2;
            w[i] = len;
        }
        int ans = Kruskal(road_num);
        printf("%d
", ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/tallisHe/p/4677463.html