并查集的应用
时间复杂度为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\n",ans); } }