2021-02-26 LuoguP1536と検索テンプレート

概要:

同時検索テンプレート-パス圧縮、ランクに応じた分散


問題の簡単な説明(問題の変換):

nの村があり、mの条件が与えられており、各条件は2つの村が相互に接続されていることを示しています。指定された2つの村が到達可能かどうかを尋ねます(必ずしも直接到達可能である必要はありません)
元の質問へのリンク:Luogu P1536 Village-Village


アルゴリズムの分析:

典型的なユニオンチェックテンプレート。最適化には、パス圧縮とランク割り当てを使用できます。
特に、この質問の出力は制御が簡単ではありません。次の式を使用できます(cin >> n >> m)戻り値を決定します。入力にcinを使用します。入力後にバッファに他のもの(文字、整数など)がない場合は、EOFを返します。EOFしばらくの間は誤りと見なされます


コードと詳細なコメント:

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

おすすめ

転載: blog.csdn.net/sddxszl/article/details/114141754