C125【模板】带权并查集 P2024 [NOI2001] 食物链
C125【模板】带权并查集 P2024 [NOI2001] 食物链_哔哩哔哩_bilibili
// 带权并查集 #include<bits/stdc++.h> using namespace std; const int N=50005; int n,k,ans; int fa[N],d[N]; //d[x]表示x到根的距离 int find(int x){ if(fa[x]==x) return x; int t=find(fa[x]); //记录新根t d[x]=d[x]+d[fa[x]]; //先更新x到新根t的距离 return fa[x]=t; //再更新fa[x],路径压缩 } int main(){ scanf("%d%d",&n,&k); for(int i=1; i<=n; i++) fa[i]=i; for(int op,x,y;k--;){ scanf("%d%d%d",&op,&x,&y); int px=find(x),py=find(y); if(x>n||y>n) ans++; else if(op==1){ //x,y是同类 if(px==py&&((d[x]-d[y])%3+3)%3!=0) ans++; //x,y在同一颗树且不在同一层,则不是同类,是假话 if(px!=py){ //x,y不在同一颗树,则合并集合 fa[px]=py; //px指向py d[px]=d[y]-d[x]; //x,y应在同一层,到根的距离应相等,d[px]+d[x]=d[y] } } else{ //x吃y if(px==py&&((d[x]-d[y])%3+3)%3!=1) ans++; //x,y在同一颗树且x不在y的下一层,则不满足x吃y,是假话 if(px!=py){ //x,y不在同一颗树,则合并集合 fa[px]=py; //px指向py d[px]=d[y]+1-d[x]; //x应在y的下一层,到根的距离应多1,d[px]+d[x]=d[y]+1 } } } printf("%d\n",ans); }
浙公网安备 33010602011771号