码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2017-10-04 22:00:13      阅读:270      评论:0      收藏:0      [点我收藏+]

标签:--   logs   解题思路   target   tar   cst   需要   sam   并查集   

题目链接:http://poj.org/problem?id=1182

题目大意:有N只动物,分别编号为1~N,所有动物都属于A,B,C中的其中一种。已知A吃B、B吃C、C吃A。按顺序给出下面的两种信息共K条。

     第一种,x和y属于同一种类。

     第二种,x吃y。

当这些信息满足以下任意一个条件时,该信息为假信息:

     ① 当前的话与前面的某些真的话冲突,就是假话。
     ② 当前的话中X或Y比N大,就是假话。
     ③ 当前的话表示X吃X,就是假话。 

需要你判断一共有多少条信息是假的。 

解题思路:

解法一:数组扩增三倍用来表示A,B,C。这种解法我是在《挑战程序设计》上看的,感觉是我比较好理解的版本。下面都是书上的原话:

对于每只动物x创建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是否在同一组等信息。

代码:

 1 #include<cstdio>
 2 const int N=5e4+5;
 3 
 4 int root[N*3];
 5 
 6 int find(int x){
 7     return root[x]==x?x:root[x]=find(root[x]);
 8 }
 9 
10 bool same(int a,int b){
11     return find(a)==find(b);
12 }
13 
14 void unite(int a,int b){
15     if(find(a)!=find(b))
16         root[find(a)]=find(b);
17 }
18 
19 //元素x,x+N,x+2*N分别代表x-A,x-B,x-C 
20 int main(){
21     int N,K,ans=0;
22     scanf("%d%d",&N,&K);
23     for(int i=1;i<=3*N;i++){
24         root[i]=i;
25     }
26     while(K--){
27         int t,x,y;
28         scanf("%d%d%d",&t,&x,&y);
29         if(x>N||y>N){
30             ans++;
31             continue;
32         }
33         if(t==1){
34             //"x,y属于同一类" 的信息 
35             if(same(x,y+N)||same(x,y+2*N))
36                 ans++;
37             else{
38                 unite(x,y);
39                 unite(x+N,y+N);
40                 unite(x+2*N,y+2*N);
41             }
42         }
43         else{
44             //"x吃y"的信息 
45             if(same(x,y)||same(x,y+2*N))
46                 ans++;
47             else{
48                 unite(x,y+N);
49                 unite(x+N,y+2*N);
50                 unite(x+2*N,y);
51             }
52         }
53     }
54     printf("%d\n",ans);
55 }

 

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

标签:--   logs   解题思路   target   tar   cst   需要   sam   并查集   

原文地址:http://www.cnblogs.com/fu3638/p/7627227.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!