hdu 1879(最小生成树kruskal)

/*

*  最小生成树,(kruskal) 

*  本题要点:当两点之间已有路时,把这两点的路长设为0,然后就是套用kruskal了 

*/

#include <cstdio>

#include <cstdlib>

#include <iostream>



using namespace std;



const int M = 5050;



int p[M];

struct edge {//边节点 

    int a;

    int b;

    int w;

}e[M];



int cmp(const void *a, const void *b) {//按权值从小到大排序 

    return (*(edge *)a).w - (*(edge *)b).w;

}



void init(int vs) {//初始化集合 

    for (int i=1; i<=vs; ++i) p[i] = i;

    return ;

} 



int find(int v) {

    if (p[v] != v) p[v] = find(p[v]);

    return p[v];

}



int join(edge e) {

    int x, y;

    x = find(e.a);

    y = find(e.b);

    if (x != y) {

        p[x] = y;

        return e.w;

    }

    return 0;

}



int kruskal(int es, int vs) {

    int ans = 0;

    init(vs);

    qsort(e, es, sizeof(edge), cmp);

    for (int i=0; i<es; ++i) ans += join(e[i]);

    return ans;

}



int main() {

    int vs, f;

    while (scanf("%d", &vs), vs) {

        int es = vs * (vs - 1) / 2;

        for (int i=0; i<es; ++i) {

            scanf("%d%d%d%d", &e[i].a, &e[i].b, &e[i].w, &f);

            if (f) e[i].w = 0;

        }

        int ans = kruskal(es, vs);

        printf ("%d\n", ans);

    }

    return 0;

}

 

你可能感兴趣的:(最小生成树)