And collect the detailed analysis of the related topic "unblocked project"

And collect the detailed analysis of the related topic "unblocked project"

The following is a topic about "parallel search set"

Unblocked project
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 a positive integer and a non negative integer, which are the number of towns N (< 1000) and the number of roads M respectively; 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: multiple roads can be connected between two cities, that is, the input of 3 3 1 2 1 2 2 1 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.
Input example:

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

Output example

1
0
2
998

The title says

The goal is to enable any two cities and towns in the province to realize transportation (but there is not necessarily a direct road connection, as long as they can reach each other indirectly through the road)

Take the following picture as an example:

It means that 9 and 3 are also unblocked. They are connected together in the same whole, but 9 and 6 are not connected. We need to build roads to connect them.

Blue cities, purple cities and yellow cities are all in a whole (set), and the cities in the same set are interconnected. Therefore, it is easy to understand that in order to connect all cities, we need to connect all sets, and build a road between sets to realize the interconnection of all cities.

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

Then, before the two roads are connected, all cities are an independent set, and their parents[i] is themselves;

We define a variable ans to represent the number of sets. There are as many sets as there are cities at the beginning. Because ANS and parents are used in multiple functions, we define ANS and parents as global variables.

void Init(int n, int parents[1001])// initialization
{
	for (int i = 0; i < n; i++)
	{
		parents[i] = i;
	}
	ans = n;
}

According to the idea of joint search set, we use the root node of the element inside to represent the set. Therefore, as long as the root nodes of the two elements are the same, we can know that they are in a set, so we need to find the root node of the element. Find the father's father until you find the root node.

int findanc(int x)//Find root + path compression
{
	return x == parents[x] ?  x :  (parents[x] = findanc(parents[x]));
}

Here, we also achieve path compression, that is, while finding the root node of the element, we also connect the element directly to the root node. In this way, we don't need to find the father's father's father to find the root node of the element next time. We only need one step to find its root node.

Entering the numbers of two cities means that the two elements are connected together, which also means that they belong to the same set.

To connect 5 and 9, just connect their root nodes together, that is, parents[findanc(a)] = findanc(b)// Let the parent node of the root node of 5 become the root node of 9, so that they are connected together

void Union(int a, int b)//union
{
	if (findanc(a) != findanc(b))//Note that if they have not been connected before (if they have been connected before, they will be in the same set, that is, their roots will be the same)
	{
		parents[findanc(a)] = findanc(b);
		ans--;//Each time the two sets are combined, one less set is set
	}
}

Finally, the road to be repaired is the number of sets minus 1, that is, ans-1;

The whole code is as follows:

#include<iostream>
using namespace std;
int ans;
int parents[1001] = { 0 };
void Init(int n, int parents[1001])// initialization
{
	for (int i = 0; i < n; i++)
	{
		parents[i] = i;
	}
	ans = n;
}
int findanc(int x)//Find root + path compression
{
	return x == parents[x] ?  x :  (parents[x] = findanc(parents[x]));
}
void Union(int a, int b)//union
{
	if (findanc(a) != findanc(b))//Note that there is no connection before
	{
		parents[findanc(a)] = findanc(b);
		ans--;
	}
}
int main()
{
	int m, n;
	cin >> n;
	
	while (n)
	{
		cin >> m;
		Init(n, parents);
		for (int i = 0; i < m; i++)
		{
			int a, b;
			cin >> a>> b;
			Union(a, b);
		}
		cout << ans - 1 << endl;
		cin >> n;
	}
	return 0;
}

If it helps you, don't forget to praise it 👍 oh
If there are omissions, please correct them
There are other contents on my home page, please pay attention ❤ I, we study together and grow together!

Tags: C C++ Algorithm

Posted on Sun, 21 Nov 2021 16:10:50 -0500 by wispas