JakeLin-Smooth Engineering Problem-Solution / Kruskal / Minimal Spanning Tree

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
0

Sample output

3
0

Title link (submittable)

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

 

Published 20 original articles · won 15 · views 217

Guess you like

Origin blog.csdn.net/qq_37414463/article/details/105375057