时间复杂度为O(m log n)
若m远大于n可以视为O(m)
一般为路径压缩
关系类并查集,以食物链为代表
个人感觉还是蛮重要的,主要是一个偏移量的关系
代码如下
#include<cstdio>
int a[150001];
int n,k,d,x,y,ans=0;
int find(int x)
{
if(x!=a[x]) a[x]=find(a[x]);
return a[x];
}
void go(int x,int y)
{
x=find(x);
y=find(y);
a[x]=y;
}
int main()
{
scanf("%d %d",&n,&k);
for(int i=1;i<=3*n;i++)
a[i]=i;
for(int i=1;i<=k;i++)
{
scanf("%d %d %d",&d,&x,&y);
if(x>n||y>n)
{
ans++;
continue;
}
if(d==1)
{
if(find(x+n)==find(y)||find(x+n*2)==find(y))
{
ans++;
continue;
}
go(x,y);
go(x+n,y+n);
go(x+2*n,y+2*n);
}
else
{
if(find(x)==find(y)||find(x+2*n)==find(y))
{
ans++;
continue;
}
go(x+n,y);
go(y+2*n,x);
go(y+n,x+2*n);
}
}
printf("%d",ans);
}
还有一类题目是带权并查集,tg这个范围应该差不多了
并查集 专题 - Virtual Judge.html
https://vjudge.net/contest/155624#problem/D
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int MAXN=200010; int fa[MAXN]; int val[MAXN]; int n,m; int findfa(int x) { if(fa[x]==-1) return x; int tmp=findfa(fa[x]); val[x]+=val[fa[x]]; return fa[x]=tmp; } int main() { int u,v,w; while(~scanf("%d %d",&n,&m)) { memset(fa,-1,sizeof fa); memset(val,0,sizeof val); int ans=0; while(m--) { scanf("%d %d %d",&u,&v,&w); u--; int xx=findfa(u); int yy=findfa(v); if(xx==yy) { if( (val[v]-val[u])!=w) ans++; } else { fa[yy]=xx; val[yy]=val[u]-val[v]+w; } } printf("%d ",ans); } }