食物链
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 52414   Accepted: 15346

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吃B,B吃C,C吃A,并给出一些条件,推断为你提供信息的人说了多少句假话。

并查集。通经常使用来检查两个元素是否在同一集合中,或者是将两个不同的集合为一个集合。

至于这道题。有神人曰。利用并查集,同一时候对每一个节点保持其到根结点的相对类别偏移量,定义为:

               0——同类;

               1——食物;

               2——天敌。

一个非常具体的解题报告,看得我五体投地:点击打开链接

这里他讲的异常具体,哪一点都有讲到,,当中60行到180行就有下边凝视的公式的解析

好厉害。,2015,7,27

#include<stdio.h>
#define M 50005
int x[M],re[M];
void init()
{
for(int i=0;i<M;i++){
x[i]=i; re[i]=0;
}
}
int find(int k)
{
int temp=x[k];
if(x[k]==k) return k;
x[k]=find(x[k]);
re[k]=(re[k]+re[temp])%3;//( 儿子的关系 + 父亲的关系 ) % 3 = 儿子对爷爷的关系
return x[k];
}
void merge(int a,int b,int fa,int fb,int d)
{
x[fa]=fb;
re[fa]=(re[b]-re[a]+d+3)%3;//d是a与b的关系,(3-re[a])是a为根节点时,他父亲的关系,(re[b]-re[a]+d+3)%3就是a的根节点与他的父亲就是b的根节点的关系 
}
int main()
{
int n,m,a,b,d,fa,fb,count=0;
scanf("%d%d",&n,&m);
init();
while(m--){
scanf("%d%d%d",&d,&a,&b);
if( a>n || b>n || (a==b && d==2) ){
count++;
continue;
}
fa=find(a);
fb=find(b);
if(fa==fb&&(re[a]-re[b]+3)%3!=d-1)//3-re[b]就得到了根节点和b的关系,re[a]+3-re[b]就是a关于b的关系 
count++;
else
merge(a,b,fa,fb,d-1);
}
printf("%d\n",count);
return 0;
}

还有第二种比較巧妙的简单的方法:

对于每仅仅动物i创建3个元素i-A, i-B, i-C, 并用这3*N个元素建立并查集。这个并查集维护例如以下信息:

① i-x 表示 “i属于种类x”。

②并查集里的每个组表示组内全部元素代表的情况都同一时候发生或不发生。

比如,假设i-A和j-B在同一个组里,就表示假设i属于种类A那么j一定属于种类B,假设j属于种类B那么i一定属于种类A。

因此,对于每一条信息。仅仅须要依照以下进行操作就能够了。

1)第一种。x和y属于同一种类———合并x-A和y-A、x-B和y-B、x-C和y-C。

2)另外一种,x吃y—————————合并x-A和y-B、x-B和y-C、x-C和y-A。

只是在合并之前须要先推断合并是否会产生矛盾。比如在第一种信息的情况下,

须要检查比方x-A和y-B或者y-C是否在同一组等信息。

(一開始我一直不明确。对于两种信息都是合并,

那么以后怎么分清究竟是同类还是捕食关系呢,或者说怎样推断是否会产生矛盾呢?

后来发现,它利用3*N的数组分3段1~N,N~2N,2N~3N分别当做是A、B、C三个种类的集合,

把全部可能符合的情况都会导入进去。尽管对于两种信息的操作都是合并。

但合并的内容是不一样的,这样就能够在合并之前推断其是否以还有一种信息合并过或者符合还有一种信息。能够自己举例来理解一下)

#include<stdio.h>
#define M 50005*3
int x[M];
void init()
{
for(int i=0;i<M;++i){
x[i]=i;
}
}
int find(int k)
{
if(x[k]==k) return k;
x[k]=find(x[k]);
return x[k];
}
void merge(int a,int b)
{
int fa=find(a); int fb=find(b);
if(fa!=fb) x[fa]=fb;
}
bool same(int a,int b)
{
return find(a)==find(b);
}
int main()
{
int n,m,a,b,c,count=0;
scanf("%d%d",&n,&m);
init();
while(m--){
scanf("%d%d%d",&c,&a,&b);
//元素a。a+N,a+2*N分别代表a-A。a-B,a-C
if(a>n || b>n ||(a==b && c==2)) {
count++;
continue;
}
if(c==1){
if(same(a,b+n) || same(a,b+2*n))
count++;
//对于第一种信息是不能出现捕食与被捕食关系的
else{
merge(a,b);
merge(a+n,b+n);
merge(a+2*n,b+2*n);
}
}
else{
if(same(a,b) || same(a,b+2*n)) count++;
//不能出现捕食同类和反捕食的情况
else{
merge(a,b+n);
merge(a+n,b+2*n);
merge(a+2*n,b);
}
}
}
printf("%d\n",count);
return 0;
}

poj 1182 食物链 &amp;&amp; nyoj 207(种类并查集)的更多相关文章

  1. poj 1182 食物链(高级的带权并查集)

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

  2. 【POJ】2492 A bug's life ——种类并查集

    A Bug's Life Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 28211   Accepted: 9177 De ...

  3. hdu 1182 A Bug's Life(简单种类并查集)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1829 题意:就是给你m条关系a与b有性关系,问这些关系中是否有同性恋 这是一道简单的种类并查集,而且也 ...

  4. POJ 1703 Find them, Catch them(种类并查集)

    Find them, Catch them Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 41463   Accepted: ...

  5. 种类并查集,Poj(1703)

    题目链接:http://poj.org/problem?id=1703 第一次做种类并查集,有的地方还不是很清楚,想了一上午,有点明白了,这里记录一下. 这里我参考的红黑联盟的题解. 关键:种类并查集 ...

  6. POJ1703--Find them, Catch them(种类并查集)

    Time Limit: 1000MSMemory Limit: 10000K Total Submissions: 32909Accepted: 10158 Description The polic ...

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

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

  8. poj 1182 食物链(种类并查集 ‘初心者’)

    题目链接:http://poj.org/problem?id=1182 借着这题可以好好理解一下种类并查集,这题比较简单但挺经典的. 题意就不解释了,中问题. 关于种类并查集结局方法也是挺多的 1扩增 ...

  9. POJ 1182食物链(分集合以及加权两种解法) 种类并查集的经典

    题目链接:http://icpc.njust.edu.cn/Problem/Pku/1182/ 题意:给出动物之间的关系,有几种询问方式,问是真话还是假话. 定义三种偏移关系: x->y 偏移量 ...

随机推荐

  1. POJ 2513 trie树+并查集判断无向图的欧拉路

    生无可恋 查RE查了一个多小时.. 原因是我N define的是250500 应该是500500!!!!!!!!! 身败名裂,已无颜面对众人.. 吐槽完了 我们来说思路... 思路: 判有向图能否形成 ...

  2. Centos 6 搭建邮箱服务器教程

    Centos 6 搭建邮箱服务器主要是是包括了Postfix, Dovecot和 MySQL了,下文我们详细的为各位介绍Centos 6 搭建邮箱服务器教程(Postfix, Dovecot和 MyS ...

  3. VUE 基础语法

    <script> //构造器 new Vue({ el: "#apps", data: { MSG: 'THIS IS A TEST Pages', h2test: ' ...

  4. 修改 Mac 默认 PHP 运行环境

    更新了自带php版本后,修改默认php环境变量 首先,创建 .bash_profile 文件 sudo nano ~/.bash_profile # 添加一行.注意 PHP5.4.10 修改成你正在运 ...

  5. Pinpoint 监控

    ####Hbase数据################ 参考: 然而没有卵用: https://blog.csdn.net/iamlihongwei/article/details/52882749? ...

  6. zookeeper单机和奇数集群

    zookeeper单机和奇数集群 链接地址:https://www.cnblogs.com/lsdb/p/7297731.html

  7. 在APP开发设计过程中:如何设计启动页面?

    心理学上有一个“7秒理论”,说的是,一个人对另一个人的印象,在初次见面的七秒内就会形成,最近更有研究表明,这个时间可能更短——不到1秒.所以初次见面所展示的形象真的很重要.同理,用户在使用APP时,每 ...

  8. 杭电2060WA

    #include<stdio.h> int main() { int n,num,p,q,i,a[]={2,3,4,5,6,7}; scanf("%d",&n) ...

  9. 使用序列号激活优动漫PAINT(附激活码)

    优动漫PAINT是一款功能强大的动漫绘图软件,简单的中文界面和丰富的笔刷操纵,再次为设计工作者带来非一般的感受!最近,有不少小伙伴提出这样的疑问:购买安装优动漫PAINT之后,不知道如何激活,在哪里输 ...

  10. c++ 优先级队列(priority_queue)

    从网上搜优先级队列用法,都是有些乱七八糟的,有几种用法都没说,直接贴代码.实在郁闷,于是自己在此归纳归纳. 废话不多说,直入主题. 优先级队列的核心是比较函数的实现. 比较函数有两种实现方法: 1.在 ...