C125【模板】带权并查集 P2024 [NOI2001] 食物链
视频链接:C125【模板】带权并查集 P2024 [NOI2001] 食物链_哔哩哔哩_bilibili
P2024 [NOI2001] 食物链 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
// 带权并查集 #include <iostream> using namespace std; const int N=50005; int n,m,k,x,y,ans; int p[N],d[N]; //d[x]表示x到根的距离 int find(int x){ if(p[x]==x) return x; int t=find(p[x]); //记录新根t d[x]=d[x]+d[p[x]]; //先更新x到新根t的距离 return p[x]=t; //再更新p[x],路径压缩 } int main(){ scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) p[i]=i; while(m--){ scanf("%d%d%d",&k,&x,&y); int px=find(x),py=find(y); if(x>n||y>n) ans++; else if(k==1){ //x,y是同类情况 //x,y在同一颗树且不在同一层,则不是同类,是假话 if(px==py&&((d[x]-d[y])%3+3)%3!=0) ans++; //x,y不在同一颗树,则合并集合 if(px!=py){ p[px]=py; //px指向py d[px]=d[y]-d[x]; //x,y应在同一层,到根的距离应相等,d[px]+d[x]=d[y] } } else{ //x吃y情况 //x,y在同一颗树且x不在y的下一层,则不满足x吃y,是假话 if(px==py&&((d[x]-d[y])%3+3)%3!=1) ans++; //x,y不在同一颗树,则合并集合 if(px!=py){ p[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); }