2021-02-26 Luogu P1536 and search template

Summary:

Concurrent search template-path compression, distribution according to rank


Brief description of the problem (problem transformation):

There are n villages and m conditions are given, and each condition indicates that two villages are connected to each other. Ask whether the given two villages are reachable (not necessarily directly reachable)
link to the original question: Luogu P1536 Village-Village


Analysis of Algorithms:

A typical union check template. You can use path compression and rank allocation for optimization.
In particular, the output in this question is not easy to control, you can use the expression (cin>>n>>m) To determine the return value. Use cin for input, if there is no other things (characters, integers, etc.) in the buffer after input, it will return EOF,EOFIs considered false in while


Code and detailed comments:

#include <iostream>
#include <stdio.h>
#include <vector>
#pragma warning(disable:4996)
using namespace std;

class UnionFind {
    
    
public:
	int count;
	vector<int> root;
	vector<int> rank;
	UnionFind(int _count) :count(_count) {
    
    
		root.resize(_count + 1);
		for (int i = 1; i <= _count; ++i)
			root[i] = i;
		rank.resize(_count + 1, 0);
	}

	int find(int x) {
    
    
		return x == root[x] ? x : root[x] = find(root[x]);
	}

	void merge(int x, int y)
	{
    
    
		int rootx = find(x);
		int rooty = find(y);
		if (rootx != rooty) {
    
    
			if (rank[rootx] < rank[rooty])
				swap(rootx, rooty);
			root[rooty] = rootx;
			if (rank[rootx] == rank[rooty]) rank[rootx]++;
			--count;
		}
	}
};

int main() {
    
    
	//freopen("in.txt", "r", stdin);
	int n, m;
	while (cin >> n >> m)
	{
    
    
		int x, y;
		UnionFind u(n);
		for (int i = 1; i <= m; ++i)
		{
    
    
			cin >> x >> y;
			u.merge(x, y);
		}
		cout << u.count-1<<endl;
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/sddxszl/article/details/114141754