POJ 1182食物链 种类并查集的经典

Posted randy-lo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 1182食物链 种类并查集的经典相关的知识,希望对你有一定的参考价值。

题目链接:http://icpc.njust.edu.cn/Problem/Pku/1182/

题意:给出动物之间的关系,有几种询问方式,问是真话还是假话。

定义三种偏移关系:

x->y 偏移量0xy同类

x->y 偏移量1xy

x->y 偏移量2xy

定义 rela[x]=rx->x;

x,y不在同一个集合中,

rx->ry=rx->x + x->y + y->ry=(rx->x)+(x->y)-(ry->y)可得

rx->ry=rela[ry]=rela[x]+rela[y]+(x->y);

由于关系仅限0,1,2,三种,对上面关系加三后取模才是正确的关系;

如果x,y在同一个集合中,

x->y=x->rx+rx->x;

所以x->y=(3-rela[x]+rela[y])%3;

种类并查集的问题我们必须清楚初始状况是什么样的还有状态的转移方程是什么。

代码如下:

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 #define maxn 50005
 5 int n,k;
 6 int fa[maxn],rela[maxn];//分别表示父亲、子节点和父节点的关系 
 7 int ans;
 8 void init()
 9 {
10     for(int i=1;i<=n;i++)
11     {
12         fa[i]=i;      /*relation:0、同类 1、吃2、被吃*/ 
13         rela[i]=0;//初始状态下它和本身在一个集合中,关系为同类 
14     }
15     ans=0;
16 }
17 int find(int x)
18 {
19     if(x==fa[x])return fa[x];
20     else
21     {
22         int tmp=fa[x];
23         fa[x]=find(fa[x]);
24     
25         rela[x]=(rela[tmp]+rela[x])%3;//更新x与x的新的根结点的关系,ppx->x=ppx->px+px->x=rela[ppx]+real[px]; 
26         return fa[x]; 
27     }                                   //向量模式,rela为rootx->x的向量方向;为保证结果在[0,2]区间内,对3取模; 
28 }
29 int main()
30 {
31     cin>>n>>k;
32     init();
33     int f,a,b; 
34     for(int i=1;i<=k;i++)
35     {
36         scanf("%d%d%d",&f,&a,&b);
37         if(a>n||b>n)
38         {
39             ans++;
40             continue;
41         }
42         if(f==2&&a==b)//x吃x ,不合法, 
43         {
44             ans++;
45             continue;
46         }
47         int px=find(a);
48         int py=find(b);
49         if(px!=py)       //如果关系还未建立则建立关系       //合并的操作和查询是否正确的操作在主函数体中一起完成 
50         {
51             fa[py]=px;
52             rela[py]=(3+rela[a]+(f-1)-rela[b])%3;
53         }
54         else
55         {
56             if(f==1&&rela[a]!=rela[b])//说是同类然而 计算得并不是,则说了假话 
57             {
58                 ans++;
59                 continue;
60             }
61             if(f==2&&(3+rela[b]-rela[a])%3!=f-1)//两者之间三种状态题目中只有两种描述方式 
62             {
63                 ans++;
64                 continue;
65             }
66         }
67         
68      } cout<<ans;
69  } 

 

以上是关于POJ 1182食物链 种类并查集的经典的主要内容,如果未能解决你的问题,请参考以下文章

poj 1182 食物链 种类并查集

POJ1182 食物链---(经典种类并查集)

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

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

食物链 POJ - 1182 (并查集的两种写法)

POJ 1182 食物链 (带权并查集 && 向量偏移)