HDU1232 unblocked project and collection query introduction classic OJ problem solution

Keywords: C++ Algorithm data structure OJ DataStructure

1, Background introduction

This is the classic example of parallel search set, and the entry level. If you want to learn this data structure, you must learn this foundation well. You can recite the template. The title source is HDU 1232, and the specific link is: http://acm.hdu.edu.cn/showproblem.php?pid=1232.

2, Title Description

Problem Description

A province investigates the urban traffic conditions and obtains the statistical table of existing urban roads, which lists the cities and towns directly connected by each road. The goal of the provincial government's "unblocked project" is to enable any two cities and towns in the province to realize traffic (but there is not necessarily a direct road connection, as long as they can reach each other indirectly through the road). How many roads need to be built at least?

Input

The test input contains several test cases. The first line of each test case gives two positive integers, namely, the number of towns N (< 1000) and the number of roads M; The subsequent M lines correspond to M roads, and each line gives a pair of positive integers, which are the numbers of the two towns directly connected by the road. For simplicity, towns are numbered from 1 to N.
Note: there can be multiple roads between the two cities, that is to say

3 3
1 2
1 2
2 1

This input is also legal
When N is 0, the input ends and the use case is not processed.

Output

For each test case, output the minimum number of roads to be built in one line.

Sample Input

4 2
1 3
4 3
3 3
1 2
1 3
2 3
5 2
1 2
3 5
999 0
0

Sample Output

1
0
2
998

3, Problem solving ideas

This problem needs to calculate the minimum number of roads between any two towns in the province. Each town in the province can be regarded as a node, and the road between each town can be regarded as a line connecting two nodes. The schematic diagram of the four groups of data given in Sample Input is as follows. Node 2 and the other three nodes in the first example have no connected roads. Therefore, to achieve the goal of traffic between any two cities and towns in the province, at least one road needs to be established; In the second example, there are only 3 nodes, which are connected to each other to form a loop, and the minimum number of road establishment is 0; In the third example, node 4 exists independently, nodes 1 and 2 are connected with each other, and nodes 3 and 5 are connected with each other. To achieve the goal, node 4 and two other groups of node groups need to be connected, and two roads are required; In the last example, the number of cities and towns is 999 and the number of roads is 0, so it is equivalent to 999 independent nodes. All connections and interworking require the construction of 998 roads.

By observing the four test cases, it is not difficult to see that the steps required to solve the problem are to connect the inter city paths given by the problem as an urban area, and then solve the number of urban areas. Finally, the number of urban areas minus 1 is the required connecting section.

After inputting the number of towns n (< 1000) and the number of roads m, initialize the parent node of each node as itself. After inputting the number of M paths, merge the parent nodes of the two nodes of each path. Finally, set the ans variable as the number of urban areas and output its - 1. It should be noted that the point of easy WA is that the cycle starts from 1, not from 0.

4, AC code

Complete code

#include<iostream>
using namespace std;
int father[1000];//Set parent node

//Basic functions of joint query set: initialization
void init(int n){
    for(int i=1;i<=n;++i){
        father[i] = i;
    }
}

//Basic function of consolidation query set: find parent node
int find(int x){
    if(father[x] == x) return x;
    return father[x]=find(father[x]);
}

//Basic function of merge query set: merge parent nodes
void unions(int a,int b){
    int aa=find(a);
    int bb=find(b);
    if(aa!=bb){
        father[aa]=bb;
    }
}

//Main function
int main(){
    int n,m;//Number of towns N and roads M
    int a,b;//Nodes a and b in each set of test cases
    while(cin>>n){
        if(n==0) break;
        cin>>m;
        init(n);
        while(m--){
            cin>>a>>b;
            unions(a,b);
        }
        int ans=0;//Number of urban areas, initialized to 0
        for(int i=1;i<=n;++i){
            if(father[i]==i) ans++;
        }
        cout<<ans-1<<endl;//Number of output cities - 1
    }
    return 0;
}

Other references

Both can be AC

#include <iostream>
using namespace std;
int numpack[1005];

int search_father(int num){
    int result=num;
    while(result!=numpack[result]){
        result=numpack[result];
    }
    return result;
}

void merge(int a,int b){
    int ka=search_father(a);
    int kb=search_father(b);
    if(ka!=kb){
        numpack[ka]=kb;
    }
}

int main(){
    int city,road;
    while(cin>>city){
        if(city==0) return 0;
        else{
            cin>>road;
        }
        for(int i=1;i<=city;i++){
            numpack[i]=i;
        }
        for(int j=1;j<=road;j++){
            int start,end;
            cin>>start>>end;
            merge(start,end);
        }
        int count=0;
        for(int k=1;k<=city;k++){
            if(numpack[k]==k) count++;
        }
        cout<<count-1<<endl;
    }
    return 0;
}

Happy writing code ~

Posted by kelseyirene on Wed, 22 Sep 2021 21:53:28 -0700