poj1287 最小生成树

题目链接在这里

题目大意

给出N个点,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 = 60;

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

int n, m;
int par[MaxN], r[MaxN];
priority_queue<Node> 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 main(){
    ios::sync_with_stdio(false);
    while(cin >> n && n){
        while(!que.empty()) que.pop();
        init();
        cin >> m;
        int x, y, val;
        rep(i, m){
            cin >> x >> y >> val;
            que.push(Node{x, y, val});
        }

        int ans = 0;
        while(--n){
            Node node = que.top();
            que.pop();
            if(check(node.x, node.y)){
                ++n;
                continue;
            }
            ans += node.val;
            unite(node.x, node.y);
        }

        cout << ans << endl;
    }

    return 0;
}

猜你喜欢

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