並查集【最全模版】
阿新 • • 發佈:2018-11-11
並查集【模版】(洛谷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;
}