算法基础之食物链

食物链

  • 核心思想:带权并查集

    • 在这里插入图片描述

      • 用距根节点和距离表示与根节点的关系
    • 求距离

      • 在这里插入图片描述
  •   	#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;
      	    }
      	```
    
  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阳光男孩01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值