【題解】POJ 1251 Jungle Roads

【題目敘述】https://vjudge.net/problem/POJ-1251
【參考】ZeroJudge d909: 公路局長好煩惱!?【題解
【解題想法】最小生成樹 (Minimum Spanning Tree, MST)

  • 題目保證 “n-1 lines that start with village labels in alphabetical order”,所以起點的 village label 不需轉換,直接用 i (Line-38)。Line-36 將道路另一端點的 village label 轉換成編號。
  • 函式 Find( ):執行並查集的 Find( )。
  • Line-51:執行並查集的 Union( )。
  • Line-53:使用 n-1 條邊後,就完成最小生成樹了。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct edge{
    int x, y, cost;
};

int n, m, a, b, p[30], ans, cnt;
char c;
vector <edge> v;
edge now;

bool cmp(edge a, edge b){
    return  a.cost < b.cost;
}

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

int main(){
    while (cin >> n){
        if (n == 0) break;
        v.clear();
        for (int i = 0; i < n-1; i++){
            cin >> c;
            cin >> m;
            for (int j = 0; j < m; j++){
                cin >> c;
                a = c - 'A'; //終點
                cin >> b; //道路維護費用
                v.push_back({i, a, b});
            }
        }
        for (int i = 0; i < n; i++){
            p[i] = i;
        }
        sort(v.begin(), v.end(), cmp);
        ans = 0;
        cnt = n-1; //需要n-1條邊
        for (int i = 0; i < v.size(); i++){
            now = v[i];
            if (Find(now.x) == Find(now.y)) continue;
            else{
                p[p[now.x]] = p[now.y];
                ans += now.cost;
                if (--cnt == 0) break;
            }
        }
        cout << ans << "\n";
    }
    return 0;
}
分享本文 Share with friends