poj1251 最小生成树

题目链接在这里

题目大意:

有n个点,下面有n - 1行,每行有一个编号X有一个数字m代表点X和m个其它点相连,然后后面有m个点以及权值。求最小生成树。

思路:

最小生成树,莽就完事了。

代码:

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

struct Node{
    int x, y, val;
    bool operator > (const Node &x) const{
        return val > x.val;
    }
};
int n;
int par[MaxN], r[MaxN];

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];
    }
}

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

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

int main(){
    priority_queue<Node, vector<Node>, greater<Node> > que;
    while(cin >> n && n){
        while(!que.empty()) que.pop();
        init();
        char x, y;
        int m, dis;
        for(int i = 1; i < n; ++i){
            cin >> x >> m;
            int xx = x - 'A';
            rep(i, m){
                cin >> y >> dis;
                int yy = y - 'A';
                que.push(Node{xx, yy, dis});
            }
        }

        int ans = 0;
        while(--n){
            Node node = que.top();
            que.pop();
            if(check(node.x, node.y)){
                ++n;
                continue;
            }
            //cout << "x:" << node.x << "\ty:" << node.y << "\tval:" << node.val << endl;
            unite(node.x, node.y);
            ans += node.val;
        }

        cout << ans << endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Never__Give_Up_/article/details/86406533