目录

题目描述

思路

完整代码



题目描述

动物王国中有三类动物 A,B,CA,B,C,这三类动物的食物链构成了有趣的环形。AA 吃 BB,BB 吃 CC,CC 吃 AA。

现有 NN 个动物,以 1 \sim N1∼N 编号。每个动物都是 A,B,CA,B,C 中的一种,但是我们并不知道它到底是哪一种。

有人用两种说法对这 NN 个动物所构成的食物链关系进行描述:

  • 第一种说法是 1 X Y,表示 XX 和 YY 是同类。
  • 第二种说法是2 X Y,表示 XX 吃 YY。

此人对 NN 个动物,用上述两种说法,一句接一句地说出 KK 句话,这 KK 句话有的是真的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。

  • 当前的话与前面的某些真的话冲突,就是假话;
  • 当前的话中 XX 或 YY 比 NN 大,就是假话;
  • 当前的话表示 XX 吃 XX,就是假话。

你的任务是根据给定的 NN 和 KK 句话,输出假话的总数。

输入格式

第一行两个整数,N,KN,K,表示有 NN 个动物,KK 句话。

第二行开始每行一句话(按照题目要求,见样例)

输出格式

一行,一个整数,表示假话的总数。

输入输出样例

输入
100 7
1 101 1
2 1 2
2 2 3
2 3 3
1 1 3
2 3 1
1 5 5
输出
3

思路

基本的并查集的概念和路径压缩等操作不多赘述,这里主要介绍一下带权并查集的概念。

带权并查集:在对并查集进行路径压缩和合并操作时,这些权值具有一定属性,即可将他们与父节点的关系,变化为与所在树的根结点关系。

我们用 dist[i] 表示 i 这个节点与其父节点权值关系。权值有三种:

  1. dist[i]% 3==0 表示这个节点与父节点是同类
  2. dist[i]%3==1 表示这个节点吃父节点
  3. dist[i]% 3==2 表示这个节点被父节点吃

如果我们知道A与B的关系,A与C的关系,那么我们必然可以推出B与C的关系。

所以,我们可以将表示当前这个节点与根节点的关系。若我们知道A与根的关系,B与根的关系,必然可以推出A与B的关系。

A与B的关系:(dist[A]- dist[B])%3

初始时,每个节点的根节点都是自己。因为初始时只清楚自己与自己的关系。

对每句话提到的两个节点,均做一遍查询根节点

        int px = find(x);int py = find(y);

对x节点,查询根节点赋值给px,对y节点,查询根节点赋值给py

px !=py 表示x和y的根节点不同,根节点相同的我们才知道这两者之间的关系,所以之前是没有一句话说了x和y的关系的,不然我们肯定会把这两个并查集合并,根节点就会相同。那么我们把px的父亲指向py。那么x节点到现在的根节点的距离为:

dist[x]+dist[px]

若x 吃 y ,则:

(dist[x]+dist[px]-dist[y]-1)% 3==0

则:

dist[px]=dist[y]-dist[x]+1

若x 与 y 是同类,则:

(dist[x]+dist[px]-dist[y])% 3==0

则:

dist[px]=dist[y]-dist[x]

px==py,表示x 和 y 的关系已由之前的话给出,只需相应判断就行。

在路径压缩时,需要同时更新dist[i]

int find(int x){if(x != p[x]){int u = find(p[x]);dist[x] += dist[p[x]];p[x] = u;}return p[x];
}

完整代码

完整代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>using namespace std;#define rep(i,j,k) for(int i=j;i<=k;i++)
#define per(i,j,k) for(int i=j;i>=k;i--)typedef long long LL;const int N = 5e4 + 10;int n,m;int p[N];int dist[N];int find(int x){if(x != p[x]){int u = find(p[x]);dist[x] += dist[p[x]];p[x] = u;}return p[x];
}int main(){scanf("%d%d",&n,&m);rep(i,1,n) p[i] = i;int res = 0;while(m --){int t,x,y;scanf("%d%d%d",&t,&x,&y);if(x > n || y > n){res += 1;continue;}if(x == y && t == 2){res += 1;continue;}int px = find(x);int py = find(y);if(px != py){if(t == 1){p[px] = py;dist[px] = dist[y] - dist[x];}else{p[px] = py;dist[px] = dist[y] - dist[x] + 1;}}else{if(t == 1){if((dist[x] - dist[y]) % 3) res += 1;}else{if((dist[x] - dist[y] - 1) % 3) res += 1;}}}printf("%d",res);return 0;
}

食物链(带权并查集)相关推荐

  1. Acwing 240食物链(带权并查集)

    AcWing 240.食物链 #include <iostream> using namespace std;//巧妙的利用余数的关系 //种类0 : d[x] % 3 == 0 //种类 ...

  2. POJ 1182 食物链 [并查集 带权并查集 开拓思路]

    传送门 P - 食物链 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit  ...

  3. ACM练级日志:带权并查集与食物链

    最近终于干掉了高中两年都没有搞定的题目:食物链,就是那个A吃B,B吃C,C吃A这道NOI的经典题.当年自己写了200多行,把自己都写碎了,也没弄出来,最近学习了带权并查集,终于搞定了这道题. 首先说说 ...

  4. poj1182 and 携程预赛2第一题 带权并查集

    题意:       动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A.  现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底 ...

  5. 【POJ - 1703】Find them, Catch them(带权并查集之--种类并查集 权为与父节点关系)

    题干: Find them, Catch them Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 36176   Accep ...

  6. POJ 2912 Rochambeau(难,好题,枚举+带权并查集)

    下面的是从该网站上copy过来的,稍微改了一点,给出链接:http://hi.baidu.com/nondes/item/26dd0f1a02b1e0ef5f53b1c7 题意:有N个人玩剪刀石头布, ...

  7. 学习笔记——拓展域并查集和带权并查集

    1,拓展域并查集 一般的并查集只能查找出各元素之间是否存在某一种相同的联系,如:a和b是亲戚关系,b和c是亲戚关系,这时就可以查找出a和c也存在亲戚关系.但如果存在多种相对的联系时一般的并查集就不行了 ...

  8. 2017乌鲁木齐区域赛I(带权并查集)

    #include<bits/stdc++.h> using namespace std; int f[200010];//代表元 long long rl[200010];//记rl[i] ...

  9. BZOJ 2303 方格染色(带权并查集)

    要使得每个2*2的矩形有奇数个红色,如果我们把红色记为1,蓝色记为0,那么我们得到了这2*2的矩形里的数字异或和为1. 对于每个方格则有a(i,j)^a(i-1,j)^a(i,j-1)^a(i-1,j ...

最新文章

  1. 封装echarts china map geo实现dispatch触发geoSelect事件高亮显示某个省份和城市,并定义复杂样式
  2. 如何避免重复提交?分布式服务的幂等性设计!
  3. oracle 数据有引号,oracle插入字符串数据时字符串中有'单引号问题
  4. 调整ViewState的位置,让你的asp.net页面对搜索引擎更友好
  5. Android ADB Server启动失败
  6. RHEL7 yum安装配置LAMP(Apache+PHP+MySql)服务器
  7. What?Java这么神奇的lambda表达式
  8. 两分钟彻底让你明白Android Activity生命周期(图文)!
  9. Ecilpse常用快捷键
  10. java循环1000000000_求十亿内所有质数的和,怎么做最快?
  11. Informatica的IDP理念:让业务部门成为真正数据受益者
  12. java星号心形代码_肿么用JAVA打印出心形的图案
  13. 案例分享——低压电力线载波通信模组(借助电源线实现远距离数据传输、宽压输入、波特率范围广、应用场景多样化)
  14. 蓝桥杯——等差素数列(c语言)
  15. Java TemplateProcessingException之Cannot execute subtraction: operands are null and #1234
  16. 前端element-ui中图片oss直传到阿里云
  17. matlab 光栅 傅里叶,【图像】【转帖】利用matlab绘制光栅条纹图像
  18. 算法篇-----粒子群算法
  19. js 通过图片链接获取file对象
  20. 正心,修身,方能齐家,治国,平天下

热门文章

  1. 【华人学者风采】林跃河 华盛顿州立大学
  2. uniapp开发微信小程序分享功能
  3. 粉条要经过什么检查才符合315?
  4. 1. Linux命令之ps:查看进程状态
  5. querylist V4 图片下载
  6. VBoxManage.exe: error: Failed to create the host-only adapter
  7. 原因: java.lang.NoClassDefFoundError: helloworld/Helloworld (wrong name: Helloworld)
  8. Linux alias编写
  9. LED显示行业之知识大全4
  10. 2023年电工杯B题详解