/* 1思路:最小生成树+kruskal 2注意把已经建好的合并 */ #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; #define MAXN 110 #define INF 0XFFFFFFF int n , m , ans; int father[MAXN]; int rank[MAXN]; struct Edge{ int x; int y; int value; int state; }e[10000]; bool cmp(Edge e1 , Edge e2){ return e1.value < e2.value; } void init_Set(){ for(int i = 1 ; i <= n ; i++){ father[i] = i; rank[i] = 1; } } int find_Set(int x){ int tmp = x; while(father[tmp] != tmp) tmp = father[tmp]; while(father[x] != tmp){ int tmp_x = father[x]; father[x] = tmp; x = tmp_x; } return tmp; } void union_Set(int x , int y){ if(rank[x] >= rank[y]){ rank[x] += rank[y]; father[y] = x; } else{ rank[y] += rank[x]; father[x] = y; } } void kruskal(){ sort(e , e+m , cmp); ans = 0; for(int i = 1 ; i <= m ; i++){ int root_x = find_Set(e[i].x); int root_y = find_Set(e[i].y); if(root_x != root_y){ if(!e[i].state) ans += e[i].value; union_Set(root_x , root_y); } } printf("%d\n" , ans); } int main(){ //freopen("input.txt" , "r" , stdin); while(scanf("%d" , &n) , n){ m = n*(n-1)/2; init_Set(); for(int i = 1; i <= m ; i++){ scanf("%d%d%d%d" , &e[i].x , &e[i].y , &e[i].value , &e[i].state); if(e[i].state) union_Set(find_Set(e[i].x) , find_Set(e[i].y)); } kruskal(); } return 0; }
时间: 2024-11-08 18:54:02