1. 程式人生 > >並查集【最全模版】

並查集【最全模版】

並查集【模版】(洛谷P3367)

初始化

int clear()
{
	for(int i = 1;i <= n;i ++)
		fa[i] = i;
	return 0;
}

尋找祖先

int find(int x)
{
	if(fa[x] == x)return x;
	return find(fa[x]);
}
優化 ——路徑壓縮
int find(int x)
{
	if(fa[x] == x)return x;
	return fa[x] = find(fa[x]);
}

合併兩個元素

int merge(int x,int y)
{ int xx = find(x); int yy = find(y); if(xx == yy)return 0; fa[xx] = yy; return 1; }
優化——按秩合併
int merge(int x,int y)
{
	int xx = fin(x);
	int yy = find(y);
	if(xx == yy)return 0;
	if(h[xx] < h[yy])
	{
		fa[xx] = yy;
		h[yy] = h[xx] + 1;
	}
	else
	{
		fa[yy] = xx;
		h[xx] = h[yy] + 1;
	}
	return
1; }

最後綜合一下

#include <iostream>
#include <cstdio>

using namespace std;

int fa[2357],n,m,k,x,y,h[2357];

int clear()
{
	for(int i =1; i <= n; i ++)
		fa[i] = i;
}

int find(int x)
{
	if(fa[x] == x)return x;
	return fa[x] = find(fa[x]);
}

int merge(int x,int y)
{
	int xx = find
(x); int yy = find(y); if(xx == yy)return 0; if(h[xx] <= h[yy]) { fa[xx] = yy; h[yy] = h[xx] + 1; } else { fa[yy] = xx; h[xx] = h[yy] + 1; } return 1; } int main() { scanf("%d%d",&n,&m); clear(); while(m --) { scanf("%d%d%d",&k,&x,&y); if(k == 1) { merge(x,y); } if(k == 2) { if(find(x) == find(y))printf("Y\n"); else printf("N\n"); } } return 0; }

P.S. 這裡沒有采用按秩合併是因為該優化有一定的侷限性,像“銀河英雄傳說”就不能按秩合併。