• P2024 [NOI2001]食物链


    算法

    并查集+扩展域

    思路

     扩展域并查集维护三个域:x_self同类,x_enemy天敌,x_eat捕食。

    他们之间的关系:

    假设有x,y两个动物,

     

    如果题目给定x和y是同类,那么合并x_self,y_self和x_enemy,y_enemy和x_eat和y_eat。

    前提条件是:x_self与y_eat不在同一个集合,x_eat与y_self不在同一个集合。

     

    如果题目给定x吃y,这里我们注意到一点,由于题目给出的食物链关系是环形,因此我们可以由x吃y”推断出“x的天敌是y的猎物

    由此得到,合并x_eat,y_self和x_self,y_enemy和x_enemy,y_eat。

    前提条件是:x_self和y_self不在一个集合,x_self和y_eat不在一个集合。

    代码

    #include <cstdio>
    #include <iostream>
    using namespace std;
    const int N = 50006;
    int fa[3*N];
    
    int get(int x) {
    	if (x == fa[x]) return x;
    	return fa[x] = get(fa[x]);
    }
    
    int main() {
    	int n, k, ans = 0;
    	cin >> n >> k;
    	for (int i = 1; i <= 3 * n; i++) fa[i] = i;
    	while (k--) {
    		int num, x, y;
    		scanf("%d %d %d", &num, &x, &y);
    		if (x > n || y > n || (num == 2 && x == y)) {
    			++ans;
    			continue;
    		}
    		if (num == 1 && (get(x) == get(y + n) || get(x + n) == get(y))) {
    			++ans;
    			continue;
    		}
    		if (num == 2 && (get(x) == get(y) || get(x) == get(y + n))) {
    			++ans;
    			continue;
    		}
    		if (num == 1) {
    			fa[get(x)] = get(y);
    			fa[get(x+n)] = get(y + n);
    			fa[get(x+2*n)] = get(y + 2 * n);
    		} else {
    			fa[get(x+n)] = get(y);
    			fa[get(x+2*n)] = get(y + n);
    			fa[get(x)] = get(y + 2 * n);
    		}
    	}
    	cout << ans << endl;
    	return 0;
    }
    

      

     

  • 相关阅读:
    普通线程类获取service,controller等spring容器类
    java拦截器获取请求完整参数
    分享几个免费IP地址查询API接口
    echarts热力地图
    echarts ajax请求demo
    mysql统计前24小时数据没有补0
    java获取来访者mac信息
    java获取本机mac物理地址
    mysql5.7以上基本配置
    springboot拦截异常信息发送邮件提醒
  • 原文地址:https://www.cnblogs.com/ruanmowen/p/12726837.html
Copyright © 2020-2023  润新知