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