食物链
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. hdoj--2509--Be the Winner(尼姆博弈)

    Be the Winner Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  2. 自己实现的一个 .net 缓存类(原创)

    public class CacheContainer { private static Hashtable ht = new Hashtable(); /// <summary> /// ...

  3. 什么是递归?用十进制转二进制的Python函数示例说明

    先上用Python写的十进制转二进制的函数代码: def Dec2Bin(dec): result = '' if dec: result = Dec2Bin(dec//2) return resul ...

  4. selenium对浏览器属性操作的方法

    最大化 方法一 //指明ChromeDriver路径 System.setProperty(Src_url_string.Chrome_Driver, Src_url_string.Driver_ad ...

  5. MVC中使用UpdateModel获取接口参数

    废话少说,直接上代码: 模型类定义: public class RequestModel { public string Name { get; set; } public float Age { g ...

  6. Android 解决toolbar标题不显示问题

    问题原因:toolbar的兼容性有问题 解决办法: setSupportActionBar(toolbar); toolbar使用步骤: 1.编写menu.xml 为了保持兼容需要这样写: andro ...

  7. 【Oracle】恢复丢失的临时表空间文件

    Oracle 11g以后,临时表空间文件是可以在重启数据库以后自动生成的(当然也可以在相同目录再建一个临时表空间文件),模拟实验如下: 1)删除临时表空间数据文件 SYS@ENMOEDU> se ...

  8. SQL 字段类型详解

    bit    整型 bit数据类型是整型,其值只能是0.1或空值.这种数据类型用于存储只有两种可能值的数据,如Yes 或No.True 或False .On 或Off.    注意:很省空间的一种数据 ...

  9. SQL数据库链接代码的解释

    SqlConnection conn = new SqlConnection(); conn.ConnectionString = "Data Source=(local);Initial ...

  10. opengl渲染时画面抖动

    渲一个大尺寸模型的时候模型的细节部分一直在闪烁.尝试: 1. 纹理用mipmap,失败. 2. 开启msaa,失败. 3. 相机近时不闪,越远闪的越厉害,怀疑是深度争夺,就把远裁剪平面调大,失败. - ...