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

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

定义三种偏移关系:

x->y 偏移量0时 x和y同类

x->y 偏移量1时 x被y吃

x->y 偏移量2时 x吃y

定义 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=;i<=n;i++)
  11. {
  12. fa[i]=i; /*relation:0、同类 1、吃2、被吃*/
  13. rela[i]=;//初始状态下它和本身在一个集合中,关系为同类
  14. }
  15. ans=;
  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])%;//更新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=;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==&&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]=(+rela[a]+(f-)-rela[b])%;
  53. }
  54. else
  55. {
  56. if(f==&&rela[a]!=rela[b])//说是同类然而 计算得并不是,则说了假话
  57. {
  58. ans++;
  59. continue;
  60. }
  61. if(f==&&(+rela[b]-rela[a])%!=f-)//两者之间三种状态题目中只有两种描述方式
  62. {
  63. ans++;
  64. continue;
  65. }
  66. }
  67.  
  68. } cout<<ans;
  69. }

下面是分集合操作的代码,集合划分成三个 i是同类集合,n+i是食物集合,2*n+i表示天敌集合,三个集合是绝对不相交的。

代码如下:(因为只有吃,被吃,吃三种状态,所以检测的时候可能错误的状态就是两种)

  1. #include<cstdio>
  2. #include<iostream>
  3. using namespace std;
  4. int fa[];
  5. int x1,x2,x3,y1,y2,y3;
  6. int n,k,d,x,y,ans=;
  7. int find(int x)
  8. {
  9. return fa[x]==x?x:fa[x]=find(fa[x]);
  10. }
  11. int main()
  12. {
  13. scanf("%d%d",&n,&k);
  14. for(int i=;i<=n*;i++) fa[i]=i;
  15. for(int i=;i<=k;i++)
  16. {
  17. scanf("%d%d%d",&d,&x,&y);
  18. if(x>n||y>n)
  19. {
  20. ans++;
  21. continue;
  22. }
  23. x1=find(x); //x表示自己
  24. x2=find(x+n); //x+n表示x的食物
  25. x3=find(x+n*); //x+2*n表示x的天敌
  26. y1=find(y); //y表示自己
  27. y2=find(y+n); //y+n表示y的食物
  28. y3=find(y+n*); //y+2*n表Y的是天敌
  29. if(d==)
  30. {
  31. if(x1==y2||y1==x2) ans++;
  32. //给出的话表明x和y是同类,但是检测发现x吃y或者y吃x,产生矛盾。
  33. //在这次检测之中和x,y的天敌集合是没有关系的,因为天敌只是对一方的天敌
  34. //比如说x的天敌可能是y的同类,也可能是食物,也可能是天敌,所以说,是没有定论的美不需要检测
  35. else
  36. {
  37. fa[x1]=y1;//由于x和y是同类,所以他们的同类,天敌,食物都是一样的,所以需要全部合并
  38. fa[x2]=y2;
  39. fa[x3]=y3;
  40. }
  41. }
  42. else
  43. {
  44. if(x1==y1||x1==y2) ans++;//给出的话中表明x吃y,但是检测发现x和y是同类或者y吃x,发生矛盾
  45. else
  46. {//集合的合并
  47. fa[y1]=x2;//y的同类都是x的食物
  48. fa[y2]=x3;//x吃y,y吃z,z吃x
  49. fa[y3]=x1;//将x集合归入y的天敌集合
  50. }
  51. }
  52. }
  53. printf("%d",ans);
  54. return ;
  55. }

POJ 1182食物链(分集合以及加权两种解法) 种类并查集的经典的更多相关文章

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

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

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

    题目链接:http://poj.org/problem?id=1703 已经不是第一次接触种类并查集了,直到今天才搞懂. 感谢红黑联盟,感谢杰哥!!! 每个节点只要关系确定,不管是不是同一个集合里面, ...

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

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

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

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

  5. POJ1703 Find them Catch them 关于分集合操作的正确性证明 种类并查集

    题目链接:http://poj.org/problem?id=1703 这道题和食物链那道题有异曲同工之处,都是要处理不同集合之间的关系,而并查集的功能是维护相同集合之间的关系.这道题中有两个不同的集 ...

  6. HDU 1198 Farm Irrigation (并检查集合 和 dfs两种实现)

    Farm Irrigation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  7. 从上面的集合框架图可以看到,Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射

    从上面的集合框架图可以看到,Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射.Collection 接口又有 3 ...

  8. Poj(1182),种类并查集

    题目链接:http://poj.org/problem?id=1182 再次熟练种类并查集,又积累点经验,和技巧,rank 0 2 1 先计算father[x] ,再更新rank[x]; #inclu ...

  9. 洛谷 P2024 [NOI2001]食物链(种类并查集,加权并查集)

    传送门 解题思路 加权并查集: 什么是加权并查集? 就是记录着每个节点到它的父亲的信息(权值等). 难点:在路径压缩和合并节点时把本节点到父亲的权值转化为到根节点的权值 怎么转化呢? 每道题都不一样Q ...

随机推荐

  1. 差旅日志i·长安&北京(更新于8.21_夜)

    大学之时,看到zealer王自如的差旅日志系列欲罢不能,扁平化的管理理念以及轻松的工作氛围,耳目一新的出差体验,抵消了部分不曾走入职场的紧张感甚至是恐惧感.如今初入职场也进入了职业生涯,特记录此次的差 ...

  2. ES6中Map数据结构学习笔记

    很多东西就是要细细的品读然后做点读书笔记,心理才会踏实- Javascript对象本质上就是键值对的集合(Hash结构),但是键只能是字符串,这有一定的限制. 1234 var d = {}var e ...

  3. [python每日一练]--0012:敏感词过滤 type2

    题目链接:https://github.com/Show-Me-the-Code/show-me-the-code代码github链接:https://github.com/wjsaya/python ...

  4. Presto单机/集群模式安装笔记

    Presto单机/集群模式安装笔记 一.安装环境 二.安装步骤 三.集群模式安装: 3.1 集群模式修改配置部分 3.1.1 coordinator 节点配置. Node172配置 3.1.2 nod ...

  5. Hadoop2.7搭建

    Hadoop最底部是 Hadoop Distributed File System(HDFS),它存储Hadoop集群中所有存储节点上的文件.HDFS(对于本文)的上一层是MapReduce 引擎,该 ...

  6. 怎么用Python写一个三体的气候模拟程序

    首先声明一下,这个所谓的三体气候模拟程序还是很简单的,没有真的3D效果或数学模型之类的,只不过是一个文字表示的模拟程序.该程序的某些地方可能不太严谨,所以也请各位多多包涵. 所谓三体气候模拟,就是将太 ...

  7. localstorage浏览器储存

    需求 a.html页面生成订单信息,b.html中调用. 通过不操作数据库,直接在浏览器自带的数据库中进行操作,当然主要是对Json数据的操作. a.html代码部分: <!--html--&g ...

  8. 微信小程序中图片上传阿里云Oss

    本人今年6月份毕业,最近刚在上海一家小公司实习,做微信小程序开发.最近工作遇到一个小问题. 微信小程序图片上传阿里云服务器Oss也折腾了蛮久才解决的,所以特意去记录一下. 第一步:配置阿里云地址: 我 ...

  9. bootstrapValidator验证的remote中data属性里获取select一直是默认值

    budgetEditionNo:{ message:'版本号输入不正确' , validators:{ notEmpty:{ message:'版本号不能为空,请填写' } , remote:{ ur ...

  10. 峰哥说技术: 05-Spring Boot条件注解注解

    Spring Boot深度课程系列 峰哥说技术—2020庚子年重磅推出.战胜病毒.我们在行动 05 峰哥说技术  Spring Boot条件注解 @EnableAutoConfiguration开启自 ...