食物链
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 63592   Accepted: 18670

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

  1. 100 7
  2. 1 101 1
  3. 2 1 2
  4. 2 2 3
  5. 2 3 3
  6. 1 1 3
  7. 2 3 1
  8. 1 5 5

Sample Output

  1. 3

Source

题目链接:POJ 1182

这题困扰了我很久,也一直不敢去做,因为看了很多的题解,都看不懂在讲什么,今天又拿出题解看了一下,总算是看懂一点门道了,先上大牛博客:POJ 1182题解

然后一定要在纸上画出这个题解中的所有关系的向量箭头,其实说是向量相加,其实还是用数字加的,只是确实非常神奇地符合向量的相加结果(大牛的思想本渣还未完全明白)。

我也就再在大牛们的题解基础上写一下我的理解,也许能帮助更多的人理解这个意思。

首先按照题解中给出的关系进行一 一对应,即我们设的关系就是要跟(D-1)这个值一致。

先排除掉最简单的两种假话:比范围N大以及自己吃自己。

然后考虑另外的情况即要开始检验两者关系是否如题目所给出的D那样;

显然当两者原本就没有关系的时候,无论D是1或2,都是真话,那这些话有什么用呢,就是给之后的假话铺垫制造制约条件。当然对于这些话的处理就是要合并(在此题这种分组并查集的写法中同一个集合就不是指同一个物种了,只要两者存在捕食关系都会在同一个集合里,比如1吃2,2吃3,3吃1,那1、2、3都会在同一个集合里,只是谁当根节点的问题)

然后如何合并呢?你可以任选合并一个方向如Fx并到Fy或Fy并到Fx(选完方向后之后的操作都要一致),但是要遵循祖先并到另一个的祖先这个原则,即原来子代不并,但是把根节点直接接到另一个根节点上去,但是这样一来被合并的根节点关系可以立马得到,但被牵连的子节点怎么办,当然就是要用路径压缩进行更新,为什么要更新,合并之后父亲节点都已经变化了,当然要更新,如何更新相信题解讲的很清楚。

然后就是解法中说的x->y这个东西,你要自己在纸上对x->y连一条方向线,我原来找半天不知道x->y在哪,感觉根本无法得知啊,然后发现x->y其实就是题中所给关系即D-1……(如果你画的没错的话第一个情况是一个四边形,第二种是一个三角形,箭头与node.relation千万别搞错)

其次就是那个向量公式里有几处可能写的比较难懂,箭头就是指向量,然后几个公式都有+3,是因为要正向取模,个人认为+3应该放到最后而不是中间。然后自己也靠着画的图和理解写了一份比较清晰的代码(绝对不是某些大牛的杀马特风格)用PPT简单地做了两张图,希望没错………

最后这题还有一个有毒的地方,不要用while(scanf(......)!=EOF),会WA

代码:

  1. #include<iostream>
  2. #include<algorithm>
  3. #include<cstdlib>
  4. #include<sstream>
  5. #include<cstring>
  6. #include<bitset>
  7. #include<cstdio>
  8. #include<string>
  9. #include<deque>
  10. #include<stack>
  11. #include<cmath>
  12. #include<queue>
  13. #include<set>
  14. #include<map>
  15. using namespace std;
  16. #define INF 0x3f3f3f3f
  17. #define CLR(x,y) memset(x,y,sizeof(x))
  18. #define LC(x) (x<<1)
  19. #define RC(x) ((x<<1)+1)
  20. #define MID(x,y) ((x+y)>>1)
  21. typedef pair<int,int> pii;
  22. typedef long long LL;
  23. const double PI=acos(-1.0);
  24. const int N=50010;
  25. struct info
  26. {
  27. int rela;
  28. int pre;
  29. };
  30. info node[N];
  31. void init()
  32. {
  33. for (int i=0; i<N; ++i)
  34. {
  35. node[i].rela=0;
  36. node[i].pre=i;
  37. }
  38. }
  39. int find(int n)
  40. {
  41. if(n==node[n].pre)
  42. return n;
  43. else
  44. {
  45. int tpre;
  46. tpre=node[n].pre;
  47. node[n].pre=find(node[n].pre);
  48. node[n].rela=(node[n].rela+node[tpre].rela)%3;
  49. return node[n].pre;
  50. }
  51. }
  52. int main(void)
  53. {
  54. int n,k,i,x,y,d;
  55. scanf("%d%d",&n,&k);
  56. init();
  57. int lie=0;
  58. for (i=0; i<k; ++i)
  59. {
  60. scanf("%d%d%d",&d,&x,&y);
  61. if(x>n||y>n)
  62. lie++;
  63. else if(d==2&&x==y)
  64. lie++;
  65. else
  66. {
  67. int fx=find(x),fy=find(y);
  68. if(fx!=fy)//根不同即此时无关系,不可能会有假话,先并掉
  69. {
  70. node[fy].pre=fx;
  71. node[fy].rela=(node[x].rela+(d-1)-node[y].rela+3)%3;
  72. }
  73. else//根相同,这才是可能出假话的地方
  74. {
  75. if(d==1)//这里两个判断是可以统一的,完全可以把if和if-else合在一起
  76. {
  77. if(d-1!=(node[y].rela-node[x].rela+3)%3)
  78. //这里为了清晰写成跟下面一样的公式,其实用node[y].rela!=node[x].rela也是可以的
  79. lie++;
  80. }
  81. else if(d==2)
  82. {
  83. if(d-1!=(node[y].rela-node[x].rela+3)%3)
  84. lie++;
  85. }
  86. }
  87. }
  88. }
  89. printf("%d\n",lie);
  90. return 0;
  91. }

POJ 1182 食物链(种类并查集)的更多相关文章

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

    记得第一次做这道题的时候,推关系感觉有点复杂,而且写完代码后一直WA,始终找不出错误. 在A了十几道并查集后,再做这道题,发现太小儿科了.发现原来之所以WA,就在于查找根节点时,没有同步更新子节点相对 ...

  2. poj 1182 食物链 (并查集)

    http://poj.org/problem?id=1182 关于并查集 很好的一道题,开始也看了一直没懂.这次是因为<挑战程序设计竞赛>书上有讲解看了几遍终于懂了.是一种很好的思路,跟网 ...

  3. POJ 1182 食物链(并查集拆点)

    [题目链接] http://poj.org/problem?id=1182 [题目大意] 草原上有三种物种,分别为A,B,C A吃B,B吃C,C吃A. 1 x y表示x和y是同类,2 x y表示x吃y ...

  4. POJ 1182 食物链(并查集+偏移向量)题解

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

  5. POJ 1182 食物链 (并查集解法)(详细注释)

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

  6. 【POJ 1182 食物链】并查集

    此题按照<挑战程序设计竞赛(第2版)>P89的解法,不容易想到,但想清楚了代码还是比较直观的. 并查集模板(包含了记录高度的rank数组和查询时状态压缩) *; int par[MAX_N ...

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

    Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到 ...

  8. POJ 1182 食物链 【并查集】

    解题思路:首先是没有思路的----然后看了几篇解题报告 http://blog.csdn.net/ditian1027/article/details/20804911 http://poj.org/ ...

  9. POJ 1182 食物链 经典并查集+关系向量简单介绍

    题目: 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有 ...

  10. poj 1182食物链(并查集)

    算法思路:把那些确定了相对关系的节点放在同一棵树里(可以同时存在多棵树,单独每棵树中节点的相对关系确定),每个节点对应的 v[] 值记录他与根节点的关系( 0:同类: 1:根吃他: 2:他吃根 ).当 ...

随机推荐

  1. eclipse原文件编码GBK-UTF8

    菜单Window-Preferences-General-Workspace,在右侧面板的Text file encoding选项中选择Other:UTF-8 上一步如果不起作用,可以尝试设置下: W ...

  2. 食物链(codevs 1074)

    题目描述 Description 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A吃B,B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并 ...

  3. POSIX线程--同时执行

    //#define _REENTRANT//#define _POSIX_C_SOURCE#include <iostream>#include <string>#includ ...

  4. 改变服务器sshd 的22的端口

    [root@v01-svn-test-server ~]# vi /etc/ssh/sshd_config Port 22 Port 5001 #新增加5001端口给sshd,现在22,5001都是s ...

  5. asp.net获取客户端IP方法(转载)

    最近web获取客户端ip,看到下面这篇文章,转载过来,一起分享(转载地址:http://www.cnblogs.com/yejun/archive/2008/02/26/1082485.html) 通 ...

  6. 【现代程序设计】homework-10

    作业地址:http://www.cnblogs.com/xinz/p/3441537.html 进行中...

  7. 记忆化搜索(DP+DFS) URAL 1183 Brackets Sequence

    题目传送门 /* 记忆化搜索(DP+DFS):dp[i][j] 表示第i到第j个字符,最少要加多少个括号 dp[x][x] = 1 一定要加一个括号:dp[x][y] = 0, x > y; 当 ...

  8. css的引入方法

    1.外部途径: 建立xx.css文件与html文件放在同一目录下 加入 <link rel="stylesheet" type="text/css" hr ...

  9. POJ2441 Arrange the Bulls(状压DP)

    题目是,有n头牛,每头牛都喜爱某几个草地,要把这n头牛分配给m个不同的它们喜爱的草地,问有几种分配方式. dp[n][S]表示前n头牛分配完毕后占用的草地集合是S的方案数 dp[0][0]=1 dp[ ...

  10. UVa11324 The Largest Clique(强连通分量+缩点+记忆化搜索)

    题目给一张有向图G,要在其传递闭包T(G)上删除若干点,使得留下来的所有点具有单连通性,问最多能留下几个点. 其实这道题在T(G)上的连通性等同于在G上的连通性,所以考虑G就行了. 那么问题就简单了, ...