poj1251 Jungle Roads 最小生成树

题目链接在这里

题目大意:

村与村之间有道路相互连通,维护道路的费用太高了,因此村里的长老决定只维护其中的一部分,并且这维护的部分仍能使村之间连通。求维护的最小成本是多少。

思路分析:

很容易想到这是求最小生成树的问题,只是对输入的处理可能有一丢丢麻烦。搞定输入之后,把最小生成树莽出来就行了。

代码如下:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#define rep(i, x) for(int i = 0; i < x; ++i)
#define clr(x) memset(x, 0, sizeof(x))
using namespace std;
const int MaxN = 105;

struct Edge{
    int x, y, val;
    bool operator < (const Edge& e) const{
        return val > e.val;
    }
};

int n;
int par[MaxN], r[MaxN];
priority_queue<Edge> que;

void init(){
    clr(r);
    rep(i, MaxN)    par[i] = i;
}

int Find(int x){
    if(x == par[x]) return x;
    return par[x] = Find(par[x]);
}

void unite(int x, int y){
    x = Find(x);
    y = Find(y);
    if(x == y)  return;
    if(r[x] < r[y]) par[x] = y;
    else{
        par[y] = x;
        if(r[x] == r[y])    ++r[x];
    }
}

bool check(int x, int y){
    return Find(x) == Find(y);
}

int kruskal(){
    init();
    int ans = 0;
    while(!que.empty()){
        Edge e = que.top();
        que.pop();
        if(check(e.x, e.y)) continue;
        ans += e.val;
        unite(e.x, e.y);
    }
    return ans;
}

int main(){
    char str[100];
    while(scanf("%d", &n), n){
        gets(str);
        //int m = (n - 1) * n / 2;
        int t;
        int x, y, val;
        rep(i, n - 1){
            scanf(" %s %d", str, &t);
            x = str[0] - 'A';
            rep(j, t){
                scanf(" %s %d", str, &val);
                y = str[0] - 'A';
                //printf("x:%d, y:%d, val:%d\n", x, y, val);
                que.push(Edge{x, y, val});
            }
        }
        printf("%d\n", kruskal());
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值