食物链
-
核心思想:带权并查集
-
- 用距根节点和距离表示与根节点的关系
-
求距离
-
-
#include<iostream>using namespace std;const int N=50010;int n,m;int p[N],d[N];//找到祖宗节点(路径压缩) 并求出对应距离int find(int x){if(p[x]!=x){int u=p[x]; //保存旧父节点d[x] += d[u];p[x] = find(p[x]); //路径压缩 所有节点指向祖宗节点}return p[x];}int main(){cin>>n>>m;for(int i=1;i<=n;i++) p[i]=i; //初始化int res=0;while(m--){int t,x,y;cin>>t>>x>>y;if(x>n||y>n) res++; //超出范围else{int px=find(x),py=find(y); //找到xy的祖宗节点if(t==1){ //说明是同类 判断对错if(px==py && (d[x]-d[y]) % 3!=0) res++; //说明在一个并查集中,且xy不同类(距离不是3的倍数)else if (px != py){ //不在一个并查集p[px] = py; //将x的祖宗节点的父节点改成y的祖宗节点d[px] = d[y] - d[x]; //xy同类->路径长度推算d[y]-d[x]}}else{ //说明是异类 判断对错if(px==py && (d[x]-d[y]-1)%3!=0) res++; //说明在一个并查集中,且x不能吃y(d[x]!=d[y]+1+3*k) else if (px != py){p[px] = py; d[px] = d[y] +1 -d[x]; //x吃y->推算d[px]长度}}}}cout<<res;}```