http://poj.org/problem?id=1182

http://codevs.cn/problem/1074/

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

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

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

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

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

 
输出描述 Output Description

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

 
样例输入 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

提示

输入文件

对7句话的分析 100 7

1 101 1  假话

2 1 2    真话

2 2 3    真话

2 3 3    假话

1 1 3    假话

2 3 1    真话

1 5 5    真话

NOI 2001 食物链(eat)

某位大神的详细到不能再详细题解:http://blog.csdn.net/c0de4fun/article/details/7318642

我就只简单说说吧

基本思路:加权并查集

第2、3种假话,特判。

第1种:

对于每一个节点,维护2个值,father:它的父节点;

relation:子节点相对于父节点的关系(这句一定要记清楚),0表示同类、1表示被父节点吃、2表示吃父节点

选定0,1,2及其代表含义的原因:

输入x,y,对于y来说

①,题目中给出的d,如果d=1,d-1=0表示同类;如果d=2,d-1=1表示y被x吃

②,子节点相对于父节点的relation=0,那么父节点相对于子节点的relation=(3-0)%3=0,同类;

子节点相对于父节点的relation=1,表示子节点被父节点吃,那么父节点相对于子节点的relation=3-1=2,表示父节点吃子节点;

子节点相对于父节点的relation=2,将上面反过来。

对于每个说法,如果给出的2个节点的父节点不在同一个集合中,就合并2棵子树,如果在同一个集合中,就判断是不是假话。

合并2棵子树:

我们这样定义:

struct node
{
      int father,relation;
}r[50001];

第1部分:是y的父节点相对于y的关系。前文中relation的定义是子节点相对于父节点的关系,所以第1部分=(3-r[y].relation)%3

第2部分:是y相对于x的关系。如果d=1,那么第2部分=d-1=0,如果d=2,表示x吃y,d-1=1,y被x吃,那么第2部分=1

第3部分:x相对于x的父节点的关系,即r[x].relation

所以合并时relation更新表达式:r[y.father]].relation=(3-r[y].relation+d-1+r[x].relation)%3

判断是不是假话:

1、如果d=1,表示说法中的x,y是同类,那么如果r[x].relation!=r[y].relation,就是假话

2、如果d=2,表示x吃y,那么y相对于x的关系就是1

b:y相对于y的父节点的值,即r[y].relation

c: x的父节点相对于x的值,即3-r[x].relation

所以判断x吃y的说法是否正确:如果(r[y].relation+3-r[x],relation)%3!=1,就是假话。

最后再说说路径压缩时relation的维护

很明显,x相对于祖先的relation=x相对于x的父节点的relation+x的父节点相对于祖先的relation。

所以路径压缩时,relation的维护:r[x].relation=r[x].relation+r[r[x].father].relation

但这里要注意,直接在代码中写这一行是错误的,因为这一句代码是在查找祖先的递归回溯时完成的,执行这一句时,r[x].father已经被更新成祖先节点,所以要事先记录x在查找祖先节点之前的父节点,用这个值代替代码中的r[x].relation

#include<cstdio>

using namespace std;

int n,k,ans;
struct node
{
int relation,father;
}e[];
int d,x,y; int find(int i)
{
if(e[i].father!=i)
{
int tmp=e[i].father;
e[i].father=find(tmp);
e[i].relation=(e[i].relation+e[tmp].relation)%;
}
return e[i].father;
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++) e[i].father=i;
for(int i=;i<=k;i++)
{
scanf("%d%d%d",&d,&x,&y);
if(x>n||y>n) ans++;
else if(d==&&x==y) ans++;
else
{
int r1=find(x);
int r2=find(y);
if(r1!=r2)
{
e[r2].father=r1;
e[r2].relation=(-e[y].relation+(d-)+e[x].relation)%;
}
else
{
if(d==)
{
if(e[x].relation!=e[y].relation) ans++;
}
else
if((e[y].relation+-e[x].relation)%!=) ans++;
}
}
}
printf("%d",ans);
}

这道题据说还可以用3个并查集来做

poj 1182/codevs 1074 食物链的更多相关文章

  1. Codevs 1074 食物链 2001年NOI全国竞赛

    1074 食物链 2001年NOI全国竞赛 时间限制: 3 s 空间限制: 64000 KB 题目等级 : 钻石 Diamond 传送门 题目描述 Description 动物王国中有三类动物 A,B ...

  2. COdevs 1074 食物链

    1074 食物链 2001年NOI全国竞赛  时间限制: 3 s 空间限制: 64000 KB 题目等级 : 钻石 Diamond 题目描述 Description 动物王国中有三类动物 A,B,C, ...

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

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

  4. CODEVS 1074 食物链 2001年NOI全国竞赛(洛谷 P2024)

    题目描述 Description 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A吃B,B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并 ...

  5. poj 1182:食物链(种类并查集,食物链问题)

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

  6. POJ 1182 食物链

    G - 食物链 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit Stat ...

  7. 食物链 poj 1182

    C - 食物链 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit Stat ...

  8. POJ 1182 食物链(种类并查集)

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

  9. poj 1182 食物链 (带关系的并查集)

      食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 44835 Accepted: 13069 Description 动 ...

随机推荐

  1. Week2-作业1

    第一章:引用:如果一架民用飞机上有一个功能,用户使用它的概率是百万分之一,你还要做这个功能么?      选择之后,这个功能是什么呢?谜底是飞机的安全功能.        个人认为,飞机的安全功能这个 ...

  2. Head First Java & 重载 覆盖

  3. js 对象的合并(3种方法)转载

    对象的合并 需求:设有对象 o1 ,o2,需要得到对象 o3 var o1 = { a:'a' }, o2 = { b:'b' }; // 则 var o3 = { a:'a', b:'b' } 方法 ...

  4. delphi 删除字符串的回车、空格、Tab键

    myStr:=StringReplace(myStr, chr(13)+chr(10), '', [rfReplaceAll]);//删除回车      myStr:=StringReplace(my ...

  5. 【硬件】- 英特尔CPU命名中的产品线后缀

    产品线后缀是CPU命名体系里最复杂最难懂的,在英特尔冗长的产品线中,CPU的后缀也是千变万化.不带后缀的CPU一般就是最普通的桌面级处理器,不管是性能还是价格都比较中庸,比如当前性价比较高的Core  ...

  6. dividend = Integer.parseInt(args[0])参数问题

    先来一段代码: package yichang; public class MyExceptionTest { public static void main(String[] args) { int ...

  7. SPOJ_NSUBSTR

    题目意思是给你一个字符串,f[x]是长度为x的子串中,出现个数最多的那个串的出现次数. 给出原串,依次输出f[1],f[2],……. 后缀自动机.对于某一个状态,right[]值的大小就是出现的次数, ...

  8. 多进程编程之守护进程Daemonize

    1.守护进程 守护进程(daemon)是一类在后台运行的特殊进程,用于执行特定的系统任务.很多守护进程在系统引导的时候启动,并且一直运行直到系统关闭.另一些只在需要的时候才启动,完成任务后就自动结束. ...

  9. python selenium2 窗口切换实例

    遍历hao123中某一区域的所有链接,点击每个链接时,会打开新的窗口,获取新窗口的title后关闭窗口,切换到初始窗口继续打开下一个链接 代码如下: #coding=utf-8 from seleni ...

  10. Power Strings POJ - 2406(next水的一发 || 后缀数组)

    后缀数组专题的 emm.. 就next 循环节../ 有后缀数组也可以做 从小到大枚举长度i,如果长度i的子串刚好是重复了len/i次,应该满足len % i == 0和rank[0] - rank[ ...