并查集算法模板:
不需要确定集合内元素个数
int findroot(int x)//查找函数
{
while(tree[x]!=x) x=tree[x];
return x;
}
void join(int x,int y)//合并函数
{
int fx=findroot(x);
int fy=findroot(y);
if(fx!=fy) tree[fx]=fy;
}
需要确定集合内元素个数
int findroot(int x)//查找函数
{
while(tree[x]!=x) x=tree[x];
return x;
}
void join(int x,int y)//合并函数
{
int fx=findroot(x);
int fy=findroot(y);
if(fx!=fy)
{
tree[fx]=fy;
num[fy]+=num[fx];
}
}
初始化
//init
for(int i=1;i<maxn;i++)
{
tree[i]=i;
vis[i]=0;//判断节点是否访问过
num[i]=1;//集合内元素个数数组
in[i]=0;//节点入度数组
out[i]=0;//节点出度数组
}
判断根节点个数
ans=0;
for(int i=1;i<maxn;i++)
{
if(vis[i]&&tree[i]==i)//判断是否连通
{
ans++;
if(ans>1)//没有连通
{
flag=1;
}
}
}
暂时遇见的几种题型
(1)判断是不是一棵树:根节点是否为1,是否存在环形区域,除根节点外其他节点入度为1。
(2)判断是否存在欧拉路:根节点只有1个,存在一个顶点的入度比出度大1,一个顶点的出度比入度大1,其他顶点入度与出度相等。
(3)判断是否存在欧拉回路:根节点只有1个,所有顶点入度与出度相等。
常见的解题思路
(1)判断根节点是否为1(必用)
(2)是否存在环(有向图1325,无向图1272)
(3)判断顶点入度、出度