B-食物链-经典并查集
现有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
以下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-食物链-经典并查集的更多相关文章
- POJ 1182 食物链 经典并查集+关系向量简单介绍
题目: 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有 ...
- HDU1232 畅通工程---(经典并查集应用)
http://acm.hdu.edu.cn/showproblem.php?pid=1232 畅通工程 Time Limit: 4000/2000 MS (Java/Others) Memory ...
- POJ 1182 食物链(经典并查集) (多组输入有时乱加也会错!)
多组输入有时乱加也会错! 这次用多组输入竟然,不用竟然对了,所以以后做题目,若是答案错误,先看加上或者删掉多组输入,看对不对 食物链 Time Limit: 1000MS Memory Lim ...
- POJ1182食物链(并查集经典好题)
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=66964#problem/E 题目思路:主要有两种思路:1.带权并查集2.挑战程 ...
- 关押罪犯 and 食物链(并查集)
题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值"( ...
- NOI2001|POJ1182食物链[种类并查集 向量]
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 65430 Accepted: 19283 Description ...
- HDU 5652 India and China Origins(经典并查集)
特别经典的一个题,还有一种方法就是二分+bfs 题意:空间内n*m个点,每个点是0或者1,0代表此点可以走,1代表不能走.接着经过q年,每年一个坐标表示此点不能走.问哪年开始图上不能出现最上边不能到达 ...
- POJ1182 食物链(并查集)
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 55260 Accepted: 16210 Description ...
- POJ 1182 :食物链(并查集)
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 43526 Accepted: 12679 Description ...
- POJ1182--食物链(经典并查集)并查集看不出来系列2
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 65906 Accepted: 19437 Description ...
随机推荐
- expect使用
expect时用与提供自动交互的工具.比如如果想要用ssh登陆服务器,每次都输入密码你觉得麻烦,那你就可以使用expect来做自动交互,这样的话就不用每次都输入密码了. 先看例子: #!/usr/bi ...
- AndroidStudio中导入jar包的方法
1.首先去下载需要的jar包 2.将jar包复制到project下的app->libs目录下(如果不存在libs目录新建一个) 3.右击该jar包,选择add as library,弹出窗口,点 ...
- hashlib 和 hmac 算法的区别
-----md5 = hashlib.md5() md5.update(password+salt) md5.hexdigest() ----- h = hmac.new(key,password,d ...
- index.html jquery
index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q ...
- Linuxpython3安装库
- (转)Jquery on()事件委派
今天浏览jQuery的deprecated列表,发现live()和die()在里面了,赶紧看了一下,发现从jQuery1.7开始,jQuery引入了全新的事件绑定机制,on()和off()两个函数统一 ...
- 【转】C# 中Linq查询所有上级节点或所有下级节点
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net ...
- 基于VC++的网络扫描器设计与实现
本文正文其实是自己的毕业论文,现在搬上来有两个原因. 一是之前大学的文档都放在百度网盘上,大概去年的时候百度网盘改版搞得不太稳定,文件夹移动次数一多里边就会有一些文件丢失了,也没有很在意.但前几天看申 ...
- 华为S5700配置端口镜像和华三S5120配置802.1X认证记录
一.说明 事情的起因是我们部门有个华为的S5700交换机,想配置端口镜像抓包但让助理买的串口线很久都还没到:而昨天测试部的同事说他们那有台华三的S5120想要配802.1X认证,但只有华为交换机的文档 ...
- 详解Linux下swig 3.0.12的手动安装过程
详解Linux下swig 3.0.12的手动安装过程 首先 从http://www.linuxfromscratch.org/blfs/view/cvs/general/swig.html上下载swi ...