Title description
The goal of the provincial government's "unblocked project" is to enable road traffic between any two villages in the province (but not necessarily directly connected by road, as long as it can be reached indirectly through the road). The urban road statistics table is now available, which lists the cost of road construction between any two towns and whether the road has been repaired. Now please write a program to calculate the minimum cost required for the smooth operation of the province.
Input
The test input contains several test cases. The first line of each test case gives the number of villages N (1 <N <100); the following N (N-1) / 2 lines correspond to the cost and construction status of roads between villages, each line gives 4 positive integers, These are the number of the two villages (numbered from 1 to N), the cost of the road between the two villages, and the state of construction: 1 means built, 0 means not built.
When N is 0, the input ends.Output
The output of each test case occupies one line, and the minimum cost required for the smooth operation of the province is output.
Sample input
4 1 2 1 1 1 3 6 0 1 4 2 1 2 3 3 0 2 4 5 0 3 4 4 0 3 1 2 1 1 2 3 2 1 1 3 1 0 0Sample output
3 0
The problem of Kruskal's minimum spanning tree is different from the basic unblocking project. Some edges already exist, so it should be set when initializing [Find Dad Array] 代码24-29行
.
[Kruskal Idea] : Each time the side with the smallest weight is taken out, if it does not form a ring, it is selected, otherwise it will continue to traverse.
[Judgment loop thinking] : There is an array f, f [n] represents the ancestor of point n, the initial points are independent, so they are all themselves. If the ancestors of the two endpoints of the edge are the same, this edge cannot be connected, otherwise it will be A loop appears.
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 100 + 10;
const int maxn2 = maxn*(maxn-1)/2;
int f[maxn];
struct edge{ // 一条边
int a; // 2端点+1权值+1状态
int b;
int weight;
int status;
}edges[maxn2];
int find(int x){ //找爹
return x==f[x]?x:(find(f[x]));
}
void init(int n,int m){
for(int i=1;i<=n;i++){
f[i]=i;
}
for(int i=0;i<m;i++){
if(edges[i].status==1){ //初始化找爹数组时将已连接的边连接
f[find(edges[i].a)] = find(edges[i].b);
}
}
}
bool cmp(edge e1,edge e2){ //将边数组升序排序
return e1.weight<e2.weight;
}
int main(){
int n;
while(scanf("%d",&n)==1 && n!=0){
int m = n*(n-1)/2;
for(int i=0;i<m;i++){
cin>>edges[i].a>>edges[i].b>>edges[i].weight>>edges[i].status;
}
init(n,m);
sort(edges,edges+m,cmp);
int ans = 0;
for(int i=0;i<m;i++){
if(edges[i].status==1) continue;
int fa = find(edges[i].a); //a的祖先
int fb = find(edges[i].b); //b的祖先
if(fa!=fb){ //不是同一个祖先,相连不会成环
f[fa] = fb; //相连(a的祖先【的祖先】是b的祖先)
ans+=edges[i].weight; //修路加其权值
}
}
cout<<ans<<endl;
}
return 0;
}