//并查集+krustal,如果已经修建道路则直接将两个点合并 #include<iostream> #include<vector> #include<algorithm> using namespace std; int father[101]; struct Edge; vector<Edge>Edge_list; void initConfig() { for (int i = 0; i < 101; i++) { father[i] = i; } Edge_list.clear(); } int findFather(int x) { if (x == father[x]) { return x; } else { father[x] = findFather(father[x]); return father[x]; } } void unionFather(int x, int y) { int x_father = findFather(x); int y_father = findFather(y); father[y_father] = father[x_father]; } struct Edge { int U, V, WEIGHT; Edge(int a, int b, int c) { U = a; V = b; WEIGHT = c; } }; bool cmp(Edge a, Edge b) { return a.WEIGHT < b.WEIGHT; } int krustal(int N_nodes, int union_count) { sort(Edge_list.begin(), Edge_list.end(), cmp); int sum = 0; int count = 0; for (int i = 0; i < Edge_list.size(); i++) { Edge e = Edge_list[i]; if (findFather(e.U) != findFather(e.V)) { sum = sum + e.WEIGHT; unionFather(e.U, e.V); count++; } if (count == N_nodes - 1 - union_count) { break; } } return sum; } int main() { int N; while (scanf("%d", &N) != EOF) { if (N == 0) { break; } initConfig(); int union_count = 0; for (int i = 0; i < N * (N - 1) / 2; i++) { int U, V, weight, conection; scanf("%d %d %d %d", &U, &V, &weight, &conection); if (conection == 0) { Edge_list.push_back(Edge(U, V, weight)); //Edge_list.push_back(Edge(V, U, weight)); } else { unionFather(U, V); union_count++; } } int sum = krustal(N, union_count); cout << sum << endl; } }