【ybtoj】【并查集】【例题4】食物链

【例题4】食物链


Link

传送门
题目


解题思路

设x+n是吃x的,x吃x+2*n,y同上
对于给出的两种关系,我们把一种可能的a、b、c列出来
在这里插入图片描述
在这里插入图片描述

PS:此处的a、b、c只是代表它们的关系,代表了谁吃谁、谁和谁同类,并不是一定是这种排列


Code

#include <iostream>
#include <cstdio>

using namespace std;

int fa[150100], n, m, c, x, y, ans;
int x0, y0, x1, y1, x2, y2, flag;

int find(int x) {
	if (fa[x] == x) return x;
	fa[x] = find(fa[x]);
	return fa[x];
}

int main() {
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= 3 * n; i++)
		fa[i] = i;
	for (int i = 1; i <= m; i++) {
		scanf("%d %d %d", &c, &x, &y);
		if (x > n || y > n || (c == 2 && x == y)) {  //先把基础的假话做了
			ans++;
			continue;
		}
		
		flag = 1;
		x0 = find(x), y0 = find(y);                   //x(x0), y(y0)
		x1 = find(x + n), y1 = find(y + n);           //x+n(x1), y+n(y1)             x/y + s*n (x/y s)这样还挺对应的
		x2 = find(x + 2 * n), y2 = find(y + 2 * n);   //x+2*n(x2), y+2*n(y2)
		
		if (c == 1) {  //保险起见,我把所有的对应
			if (x1 == y0 || x1 == y2 || x0 == y1 || x0 == y2 || x2 == y1 || x2 == y0) {
				ans++, flag = 0;
			}
		} else {
			if (x1 == y1 || x1 == y0 || x0 == y0 || x0 == y2 || x2 == y1 || x2 == y2) {
				ans++, flag = 0;
			}
		}
		
		if (!flag) continue;
		
		if (c == 1) {   //把同类并查集
			fa[x0] = y0, fa[x1] = y1, fa[x2] = y2;
		} else {
			fa[x0] = y1, fa[x2] = y0, fa[x1] = y2;
		}
	}
	printf("%d", ans);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值