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

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

第一种说法是"1 X Y",表示X和Y是同类。

第二种说法是"2 X Y",表示X吃Y。

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

1) 当前的话与前面的某些真的话冲突,就是假话;

2) 当前的话中X或Y比N大,就是假话;

3) 当前的话表示X吃X,就是假话。

你的任务是根据给定的N(1 <= N <= 50,000)和K句话(0 <= K <= 100,000),输出假话的总数。

Input

第一行是两个整数N和K,以一个空格分隔。

以下K行每行是三个正整数 D,X,Y,两数之间用一个空格隔开,其中D表示说法的种类。

若D=1,则表示X和Y是同类。

若D=2,则表示X吃Y。

Output

只有一个整数,表示假话的数目。

Sample Input

100 7
1 101 1
2 1 2
2 2 3
2 3 3
1 1 3
2 3 1
1 5 5

Sample Output

3

每两个动物间三种关系:同类,吃和被吃。然后判断断言d x y假话的个数。

并查集的归类fa[]指当前确定的关系,具体是什么关系用别的数组用值表示,比如带权值的,同类或者互吃(?)关系的。。

用fa[a],re[a]分别存和a有关的集合中的代表元素序号,和x与其关系。为了程序简便,一种给三种关系分别标识的方案为:同类 0,x吃fa[a]为1,x被fa[a]吃为-1。然后在find()中需要更新re[a]为相对find(fa[a])的关系时,找规律简化写作:

if(re[a]==re[fa[a]]) re[a] = -re[a];
else re[a] = re[a]+re[fa[a]];

解释:如果re[a]==re[fa[a]],就是a与fa[a]、fa[a]与find(fa[a])的关系一样,即吃,同类,被吃。因为三种之间关系是a吃b b吃c c吃a,则a吃fa[a]吃find(fa[a]),那么a被find(fa[a])吃。同类的话,因为-0=0,所以对应的上。else中类似,写一下能发现符合规律。。还有一种方案是同类0 吃2 被吃1,然后见:https://blog.csdn.net/libing923/article/details/8240995/

嗯,这个也挺像函数的,还有点像离散数学里的关系的合成,所以来一个函数,compose(rea, reb),其中b=fa[a],rea=re[a],reb=re[b],返回rea,reb两个关系的合成结果。

新断言d x y时,先根据题目描述x y不能大于n,然后如果x==y 判断d是否为1,不是就ans++。过了这两个判断条件后判断x y是不是已经在一个集合(就是能否根据已知确定x y关系)在的话判断是否符合,不在就把这个新关系加入进去:

 if (x>n || y>n)
ans++;
else if (x==y) {
ans+=(d==);
}
else {
rx = finf(x); ry = finf(y);//找xy的代表findfather,并更新其与代表的关系
if (rx == ry) { //如果同一个代表,可以确定关系:
ans+=(re[x] != compose((d-), re[y]));//注1
}
else { //新关系加入
fa[ry]=rx;
re[ry] = compose(compose(-re[y], -(d-)), re[x]);//注2
}
}

注1:判断x与y的关系是否与d一样。d-1后恰好表示x对y的关系(d-1==0,xy同类;==1,x吃y),而re[x]表示x对rx/ry的关系,re[y]表示y对rx/ry的关系,所以合成d-1和re[y]应得到x对rx的关系,也就是相等,所以可以这么写

注2:-re[y]表示ry对y的关系(多了个负号),各种值与y对re[y]相反。其余 同理,rx ry x y ,有三层关系,ry->y->x->rx,最后得到re[ry]对其新爸爸的关系了。嗯,也可以写fa[rx]=ry,就是让ry当rx和ry之前各自所代表的一直关系的集合中所有元素合并后的新爸爸。然后更新re[rx]也是一样的。

哎,写之前习惯性的加了个while(EOF!=scanf())结果WA,彷徨之中去了竟然就AC了。。就AC了。。嗦不粗话

还有初始化的时候要初始化re[i],因为这个都是相对代表的值,代表必须是“清白的”。。

总:

 #include <cstdio>
#include <cstring> #define ll long long
#define MAXN 50005 #define SIM 0
#define EAT 1
#define EAN -1 int fa[MAXN], re[MAXN]; int n, k;
int d, x, y;
int rx, ry;
int ans=; int compose(int a, int b) {
if (a==b)return -a;
else return a+b;
} int finf(int a) {
if (fa[a] == a) return a; int root = finf(fa[a]);
re[a] = compose(re[a], re[fa[a]]);
return fa[a] = root;
} int main()
{
scanf("%d%d", &n, &k);
for (int i = ; i <= n; i++) fa[i] = i, re[i] = ;
ans = ;
for(int i = ; i < k; i++) {
scanf("%d%d%d", &d, &x, &y);
if (x>n || y>n)
ans++;
else if (x==y) {
ans+=(d==);
}
else {
rx = finf(x); ry = finf(y);
if (rx == ry) {
ans+=(re[x] != compose((d-), re[y]));
}
else {
fa[ry]=rx;
re[ry] = compose(compose(-re[y], -(d-)), re[x]);
}
}
}
printf("%d\n", ans); return ;
}

B-食物链-经典并查集的更多相关文章

  1. POJ 1182 食物链 经典并查集+关系向量简单介绍

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

  2. HDU1232 畅通工程---(经典并查集应用)

    http://acm.hdu.edu.cn/showproblem.php?pid=1232 畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory ...

  3. POJ 1182 食物链(经典并查集) (多组输入有时乱加也会错!)

      多组输入有时乱加也会错! 这次用多组输入竟然,不用竟然对了,所以以后做题目,若是答案错误,先看加上或者删掉多组输入,看对不对 食物链 Time Limit: 1000MS   Memory Lim ...

  4. POJ1182食物链(并查集经典好题)

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=66964#problem/E 题目思路:主要有两种思路:1.带权并查集2.挑战程 ...

  5. 关押罪犯 and 食物链(并查集)

    题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值"( ...

  6. NOI2001|POJ1182食物链[种类并查集 向量]

    食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 65430   Accepted: 19283 Description ...

  7. HDU 5652 India and China Origins(经典并查集)

    特别经典的一个题,还有一种方法就是二分+bfs 题意:空间内n*m个点,每个点是0或者1,0代表此点可以走,1代表不能走.接着经过q年,每年一个坐标表示此点不能走.问哪年开始图上不能出现最上边不能到达 ...

  8. POJ1182 食物链(并查集)

    食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 55260   Accepted: 16210 Description ...

  9. POJ 1182 :食物链(并查集)

    食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 43526   Accepted: 12679 Description ...

  10. POJ1182--食物链(经典并查集)并查集看不出来系列2

    食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 65906   Accepted: 19437 Description ...

随机推荐

  1. 『高性能模型』轻量级网络ShuffleNet_v1及v2

    项目实现:GitHub 参考博客:CNN模型之ShuffleNet v1论文:ShuffleNet: An Extremely Efficient Convolutional Neural Netwo ...

  2. multiThread (一)

    并发系列(1)之 Thread 详解   阅读目录 一.线程概述 二.线程状态 三.源码分析 1. native注册 2. 构造方法和成员变量 3. start 方法 4. exit 方法 5. 弃用 ...

  3. Android proguard混淆签名打包出现"android proguard failed to export application"解决方案

    刚刚接触安卓,不是很熟悉.发现之前可以正常打包的项目出现添加混淆再进行打包签名的APK之后提示"android proguard failed to export application&q ...

  4. Linux和windows 平台下启动和关闭mysql服务

    Linux平台下启动和关闭mysql服务 一.linux下查看mysql服务的两种方式: 方式一: [root@localhost bin]ps -ef|grep mysql 方式二: [root@l ...

  5. 调试 kafka manager 源码

    前提:可以上外网. kafka manager 是一款优秀的监控 kafka 的工具,采用 scala 语言编写,如何调试 kafka manager 呢? kafka manager 使用 play ...

  6. javascript 十进制转换为二进制

    1.十进制转换为二进制 var toBin = (n) => { if(n == 0) return '0'; var res = ''; while(n != 0) { res = n % 2 ...

  7. 转发:Webstorm 2017 破解激活下载

    有用过一下,但是觉得比sublime重量太多,但是随着后来用node的开始,发现需要打造个web前端神器才能满足我的需求,于是乎重拾webstorm,目前发现11是新的版本,对node,npm支持性更 ...

  8. java----判断闰年和平年

    public class year{ public static void main(String[] args){ int year=2010; if((year%4==0&&yea ...

  9. 配置合适的Visual Studio 2017 开发环境(其它版本的也适用)

    1.VS 安装完成后,可以重新配置合适的开发环境 第一步: 第二步: 第三步: 第四步:选择合适自己的开发环境 这里我选择常规,具体的可以看窗口右边的说明

  10. Spark 中Java实现数据库Row转Rating

    Dataset<Row> ratings = mlsc.sql("SELECT user,movie,rating FROM data");JavaRDD<Row ...