食物链

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 94930   Accepted: 28666

Description:

动物王国中有三类动物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

题解:

这题用并查集来做,可以从两个角度来思考,一是普通的并查集,另一个是带权并查集。

先说第一种,我们知道这是一个环状结构,A->B->C->A,题目中判断一句话是否为假话就是看是否与前面的冲突。我们可以这么考虑,开三个集合,表示种类A,B,C,由于目前我们现在不知道x,y属于哪个种类,所以在合并集合的时候都考虑一下(利用几个集合来维护之间的关系)。

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std; const int N = ;
int f[N];
int n,k,ans; int find(int x){return f[x]==x ? x : f[x]=find(f[x]);} bool same(int x,int y){
return find(x)==find(y);
} void Union(int x,int y){
int fx=find(x),fy=find(y);
f[fx]=fy;
} int main(){
scanf("%d%d",&n,&k);
for(int i=;i<=*n+;i++) f[i]=i;
while(k--){
int op,x,y;
scanf("%d%d%d",&op,&x,&y);
if(x< || y< ||x>n ||y>n){
ans++;continue ;
}
int fx=find(x),fy=find(y);
if(op==){
if(same(x,y+n) ||same(x,y+*n)){
ans++;continue;
}
Union(x,y);Union(x+n,y+n);Union(x+*n,y+*n);
}else{
if(same(x,y) || same(x,y+*n)){
ans++;continue ;
}
Union(x,y+n);Union(x+n,y+*n);Union(x+*n,y);
}
}
printf("%d",ans);
return ;
}

再来说带权并查集。

我们用个数组r表示当前结点与父节点的关系,由于这是个环状关系,所以关系是可以传递的,比如r[p]=1代表p吃q,r[q]=1代表q吃z,那么p与z的关系就是z吃p,合并父亲后即是r[p]=2。

具体r的定义以及代码细节可以自己思考一下怎么处理(我想了几十分钟/伤心)

代码如下:

//带权并查集
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std; const int N = 5e4+;
int f[N],r[N]={};
int n,k,ans=; int find(int x){
if(f[x]==x) return x;
int tmp = f[x];
f[x]=find(f[x]);
r[x]=(r[x]+r[tmp])%;
return f[x];
} int main(){
scanf("%d%d",&n,&k);
for(int i=;i<=n+;i++) f[i]=i;
while(k--){
int op,x,y;
scanf("%d%d%d",&op,&x,&y);
if(x< || y>n ||x>n ||y<){ans++;continue ;}
int fx=find(x),fy=find(y);
if(fx==fy){
if((r[x]-r[y]+)%!=op-) ans++;
}else{
f[fy]=fx;
if(op==) r[fy]=(r[x]+(-r[y]))%;
else r[fy]=(r[x]+(-r[y])+op);
}
}
printf("%d",ans);
return ;
}

POJ1182:食物链(并查集)的更多相关文章

  1. POJ-1182 食物链 并查集(互相关联的并查集写法)

    题目链接:https://cn.vjudge.net/problem/POJ-1182 题意 中文题目,就不写了哈哈 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃 ...

  2. [poj1182]食物链(并查集+补集)

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

  3. POJ-1182 食物链---并查集(附模板)

    题目链接: https://vjudge.net/problem/POJ-1182 题目大意: 中文题,不多说. 思路: 给每个动物创建3个元素,i-A, i-B, i-C i-x表示i属于种类x,并 ...

  4. poj1182食物链--并查集

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

  5. POJ1182 食物链 并查集

    #include<iostream>#include<stdio.h>#include<string.h>using namespace std;const int ...

  6. 编程算法 - 食物链 并查集 代码(C)

    食物链 并查集 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 有N仅仅动物, 分别编号为1,2,...,N. 全部动物都属于A,B,C中的一种 ...

  7. 【poj1182】食物链--并查集扩展域

    Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 109341   Accepted: 33191 Description 动物 ...

  8. POJ-1182 分组并查集

    今天刚发现,之前做的并查集只是贴模板基本就能过,题意改变一点,自己还是不懂,其实我还没入门呢... 题意:食物链,A吃B,B吃C,C吃A,输入m组数据: 1 a b:a 和 b 是同一类 2 a b: ...

  9. POJ 1182 (经典食物链 /并查集扩展)

    (參考他人资料) 向量偏移--由"食物链"引发的总结 http://poj.org/problem?id=1182这道食物链题目是并查集的变型.非常久曾经做的一次是水过的,这次 ...

随机推荐

  1. Java学习笔记九:Java的循环跳转语句

    Java的循环跳转语句 一:Java循环跳转语句之break: 生活中,我们经常会因为某些原因中断既定的任务安排.如在参加 10000 米长跑时,才跑了 500 米就由于体力不支,需要退出比赛.在 J ...

  2. 一个新晋IT行业的努力Duiker

      亲爱的朋友,你好!   我很开心能以这么一篇博客来开始我的IT努力之路.我叫Duiker,是一名软件工程专业的学生,想通过写博客来提升自己,充实自我. 首先,我要确立自己的学习编程目标: 1.将算 ...

  3. Hystrix入门指南

    Introduction 1.Where does the name come from? hystrix对应的中文名字是“豪猪”,豪猪周身长满了刺,能保护自己不受天敌的伤害,代表了一种防御机制,这与 ...

  4. mysql_connect(): [2002] No such file or directory

    在mac中搭建php的开发环境 1. apach ---- 推荐用MAMP.你只要把你的php文件/项目放入到htdocs(/Applications/MAMP/htdocs)目录下,启动mamp,输 ...

  5. JVM运行内存分配和回收

    本文来自网易云社区 作者:吕宗胜 Java语言与C语言相比,最大的特点是编程人员无需过多的关心Java的内存分配和回收,因为所有这一切,Java的虚拟机都帮我们实现了.JVM的内存管理,大大降低了开发 ...

  6. 【连载】Maven系列(三) 进阶

    相关文章: 1.<用起来超爽的Maven——入门篇> 2.<用起来超爽的Maven——进阶篇> 一.Maven坐标: Maven世界拥有大量需要构建jar文件,我们需要找一个用 ...

  7. mysql 查询当月天数

    SELECT day(LAST_DAY('2018-02-01')) 思路: 先通过LAST_DAY() 查找当月最后一天,然后通过day()返回天数.

  8. 【个人训练】(POJ1276)Cash Machine

    最近的很多题解应该都是dp相关的了,emmm因为dp对我而言思考难度比较大,那么为了理顺自己的思路当然只能通过写blog整理了.愿我能成功搞定dp这个大关!(至少中等难度的dp要能够解决啊o(TヘTo ...

  9. Linux-Shell脚本编程-学习-5-Shell编程-使用结构化命令-if-then-else-elif

    if-then语句 if-then语句格式如下 if comman then command fi bash shell中的if语句可鞥会和我们接触的其他if语句的工作方式不同,bash shell的 ...

  10. Selenium 启动无头浏览器,只有chrome 和 firefox的,没有IE

    使用无头浏览器,可以避免掉不确定的弹出框对脚本稳定性的影响,还能在脚本执行过程中省略掉了css 加载的时间. 以下是Selenium 启动无头浏览器的方法,只有chrome 和 firefox的. p ...