nyoj--38 布线问题(最小生成树)

nyoj 38

题解

计算最小生成树的权重,然后加上花费最小的那个顶点的值。
Kruskal算法如下:

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

const int maxn = 500 + 10;
int   n, e;

struct Edge{
    int u, v, c;
    Edge(int u, int v, int c):u(u), v(v), c(c){}
};
vector edges;
int p[maxn];

int find(int x) { return x == p[x] ? x : p[x] = find(p[x]); }
int cmp(const Edge& e1, const Edge& e2) { return e1.c < e2.c; }

int solve()
{
    for(int i = 0; i <= n; ++i) p[i] = i;
    sort(edges.begin(), edges.end(), cmp);

    int ans = 0;
    for(int i = 0; i < e; ++i)
    {
        int u = edges[i].u, v = edges[i].v, c = edges[i].c;
        u = find(u), v = find(v);
        if(u != v){
            p[u] = v;
            ans += c;
        }
    }
    return ans;
}

int main()
{
    //freopen("data.in", "r", stdin);
    int t;

    for(cin >> t; t--; )
    {
        edges.clear();
        int a, b, c;
        cin >> n >> e;
        for(int i = 0; i < e; ++i){
            scanf("%d %d %d", &a, &b, &c);
            edges.push_back(Edge(a, b, c));
        }
        int maxcost = 1 << 30, tmp;
        for(int i = 0; i < n; ++i){
            scanf("%d", &tmp);
            maxcost = min(maxcost, tmp);
        }
        cout << solve() + maxcost << endl;
    }

    return 0;
}

你可能感兴趣的:(图论,图论--生成树)