AcWing 240. 食物链

Posted MangataTS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AcWing 240. 食物链相关的知识,希望对你有一定的参考价值。

题目连接

https://www.acwing.com/problem/content/description/242/

思路1

通过带权并查集来解决这个问题,我们构建一个这样的关系,我们对链的长度mod 3

  • 如果是0那么我们假定是A类说明和根节点是同类,可以吃C类
  • 如果是1那么我们假定是B类说明可以吃根节点也就是A类
  • 如果是2那么我们假定是C类,说明可以吃B类

这样我们就根据链的深度对三类做了一个划分,那么我们想做的关系判断也就不难了,详情请看代码

思路2

通过种类并查集解决这个问题

代码

#include<bits/stdc++.h>
using namespace std;
//----------------自定义部分----------------
#define ll long long
#define mod 1000000009
#define endl "\\n"
#define PII pair<int,int>

int dx[4]=0,-1,0,1,dy[4]=-1,0,1,0;

ll ksm(ll a,ll b) 
	ll ans = 1;
	for(;b;b>>=1LL) 
		if(b & 1) ans = ans * a % mod;
		a = a * a % mod;
	
	return ans;


ll lowbit(ll x)return -x & x;

const int N = 2e6+10;
//----------------自定义部分----------------
int n,m,q,fa[N],d[N];

void init()
	for(int i = 1;i <= n; ++i) fa[i] = i;


int find(int x)
	int t = x;
	int sum = 0;
	while(t != fa[t]) sum += d[t],t = fa[t];
	while(x != fa[x]) 
		int temp1 = fa[x];//存储fa[x]的点
		int temp2 = d[x];//存储x到fa[x]的距离
		fa[x] = t;
		d[x] = sum;//直接更新到祖先节点的距离
		sum -= temp2;//减去x到fa[x]的距离
		x = temp1;
	
	return x;


int main()

	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout.tie(nullptr);
	
	cin>>n>>m;
	init();
	int D,x,y;
	int ans = 0;
	for(int i = 1;i <= m; ++i) 
		cin>>D>>x>>y;
		if(x > n || y > n) ans++;
		else
			int xx = find(x);
			int yy = find(y);
			if(D == 1)
				if(xx == yy && (d[y]-d[x]) % 3) ans++;//如果在一个集合里面但是不是同一个种族
				else if(xx != yy)//不在同一个集合里面所以无法判断真假,所以我们将其视为一个集合
					fa[xx] = yy;
					d[xx] = d[y]-d[x];//如果在同一层那么应该xx比yy少d[y]-d[x]层
				
			
			else
				if(xx == yy && (d[x]-d[y]-1) % 3) ans++;//如果在同一个集合但是不是x吃y的关系
				else if(x == y) ans++;//相同的动物
				else if(xx != yy)
					fa[xx] = yy;
					d[xx] = d[y]-d[x] + 1;//因为是x吃y,那么x应该比y多一层
				
			
		
		
	
	cout<<ans<<endl;
	
	return 0;

以上是关于AcWing 240. 食物链的主要内容,如果未能解决你的问题,请参考以下文章

# [acwing 240] 食物链 [并查集]

AcWing 240. 食物链

ACWing 240. 食物链 带权并查集

AcWing:240. 食物链(扩展域并查集)

240. 食物链(并查集+数论)

剑指Offer打卡day43—— ACWing 88. 树中两个结点的最低公共祖先