P - 食物链

Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u

Appoint description: 
System Crawler  (2015-01-27)

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

先吐槽一下关于多组样例的问题,闲话也不多说,这题网上大牛各种神奇的题解都有,第一份代码是常规带权并查集的做法,不多谈,我主要想谈一下第二份代码的思路。

如果我们换一个思路,把1--n看成与自身同类的集合,1+n--2*n看成自己吃的集合,1+2*n--3*n看成吃自己的集合,那么问题便简单多了~~~

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdlib>
  4. #include<cstdio>
  5. #include<algorithm>
  6. #include<cmath>
  7. #include<queue>
  8. #include<map>
  9. #include<set>
  10. #include<stack>
  11. #include<string>
  12.  
  13. #define N 50005
  14. #define M 105
  15. #define mod 1000000007
  16. //#define p 10000007
  17. #define mod2 1000000000
  18. #define ll long long
  19. #define LL long long
  20. #define eps 1e-6
  21. #define inf 100000000
  22. #define maxi(a,b) (a)>(b)? (a) : (b)
  23. #define mini(a,b) (a)<(b)? (a) : (b)
  24.  
  25. using namespace std;
  26.  
  27. int n,m;
  28. int f[N];
  29. int r[N];
  30. int ans;
  31.  
  32. void ini()
  33. {
  34. ans=;
  35. int i;
  36. for(i=;i<=n;i++){
  37. f[i]=i;
  38. r[i]=;
  39. }
  40. }
  41.  
  42. int find(int x)
  43. {
  44. int fa;
  45. if(f[x]!=x)
  46. {
  47. fa=find(f[x]);
  48. r[x]=(r[x]+r[ f[x] ])%;
  49. f[x]=fa;
  50. }
  51. return f[x];
  52. }
  53.  
  54. void merge(int x,int y,int d)
  55. {
  56. int a,b;
  57. a=find(x);
  58. b=find(y);
  59. if(a==b){
  60. return;
  61. }
  62. f[b]=a;
  63. r[b]=(-r[y]+r[x]+d)%;
  64. }
  65.  
  66. void solve()
  67. {
  68. int d,x,y;
  69. int a,b;
  70. int re;
  71. int i;
  72. for(i=;i<=m;i++){
  73. scanf("%d%d%d",&d,&x,&y);
  74. if(x>n || y>n){
  75. ans++;continue;
  76. }
  77. if(d== && x==y){
  78. ans++;continue;
  79. }
  80. a=find(x);
  81. b=find(y);
  82. re=(-r[x]+r[y])%;
  83. if(a==b && re!=d-){
  84. ans++;continue;
  85. }
  86. //printf(" i=%d\n",i);
  87. merge(x,y,d-);
  88. }
  89. }
  90.  
  91. void out()
  92. {
  93. printf("%d\n",ans);
  94. }
  95.  
  96. int main()
  97. {
  98. //freopen("data.in","r",stdin);
  99. //freopen("data.out","w",stdout);
  100. //scanf("%d",&T);
  101. //for(int ccnt=1;ccnt<=T;ccnt++)
  102. //while(T--)
  103. //while(scanf("%d%d",&n,&m)!=EOF)
  104. scanf("%d%d",&n,&m);
  105. {
  106. ini();
  107. solve();
  108. out();
  109. }
  110. return ;
  111. }

如果我们换一个思路,把1--n看成与自身同类的集合,1+n--2*n看成自己吃的集合,1+2*n--3*n看成吃自己的集合,那么问题便简单多了~~~

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdlib>
  4. #include<cstdio>
  5. #include<algorithm>
  6. #include<cmath>
  7. #include<queue>
  8. #include<map>
  9. #include<set>
  10. #include<stack>
  11. #include<string>
  12.  
  13. #define N 50005
  14. #define M 105
  15. #define mod 1000000007
  16. //#define p 10000007
  17. #define mod2 1000000000
  18. #define ll long long
  19. #define LL long long
  20. #define eps 1e-6
  21. #define inf 100000000
  22. #define maxi(a,b) (a)>(b)? (a) : (b)
  23. #define mini(a,b) (a)<(b)? (a) : (b)
  24.  
  25. using namespace std;
  26.  
  27. int n,m;
  28. int f[*N];
  29. int ans;
  30.  
  31. void ini()
  32. {
  33. ans=;
  34. int i;
  35. for(i=;i<=*n;i++){
  36. f[i]=i;
  37. }
  38. }
  39.  
  40. int find(int x)
  41. {
  42. int fa;
  43. if(f[x]!=x)
  44. {
  45. fa=find(f[x]);
  46. f[x]=fa;
  47. }
  48. return f[x];
  49. }
  50.  
  51. void merge(int x,int y)
  52. {
  53. int a,b;
  54. a=find(x);
  55. b=find(y);
  56. if(a==b){
  57. return;
  58. }
  59. f[b]=a;
  60. }
  61.  
  62. void solve()
  63. {
  64. int d,x,y;
  65. int a,b;
  66. int fx,sx;
  67. int i;
  68. for(i=;i<=m;i++){
  69. scanf("%d%d%d",&d,&x,&y);
  70. if(x>n || y>n){
  71. ans++;continue;
  72. }
  73. if(d== && x==y){
  74. ans++;continue;
  75. }
  76. a=find(x);
  77. b=find(y);
  78. fx=find(x+n);
  79. sx=find(x+*n);
  80. if(d==){
  81. if(b==fx || b==sx){
  82. ans++;continue;
  83. }
  84. else{
  85. merge(x,y);
  86. merge(x+n,y+n);
  87. merge(x+*n,y+*n);
  88. }
  89. }
  90. else{
  91. if(b==a || b==sx){
  92. ans++;continue;
  93. }
  94. else{
  95. merge(x+n,y);
  96. merge(x+*n,y+n);
  97. merge(x,y+*n);
  98. }
  99. }
  100. }
  101. }
  102.  
  103. void out()
  104. {
  105. printf("%d\n",ans);
  106. }
  107.  
  108. int main()
  109. {
  110. //freopen("data.in","r",stdin);
  111. //freopen("data.out","w",stdout);
  112. //scanf("%d",&T);
  113. //for(int ccnt=1;ccnt<=T;ccnt++)
  114. //while(T--)
  115. //while(scanf("%d%d",&n,&m)!=EOF)
  116. scanf("%d%d",&n,&m);
  117. {
  118. ini();
  119. solve();
  120. out();
  121. }
  122. return ;
  123. }

POJ 1182 食物链 [并查集 带权并查集 开拓思路]的更多相关文章

  1. poj 1182 食物链(高级的带权并查集)

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

  2. 浅谈并查集&种类并查集&带权并查集

    并查集&种类并查集&带权并查集 前言: 因为是学习记录,所以知识讲解+例题推荐+练习题解都是放在一起的qvq 目录 并查集基础知识 并查集基础题目 种类并查集知识 种类并查集题目 并查 ...

  3. 【POJ 1984】Navigation Nightmare(带权并查集)

    Navigation Nightmare Description Farmer John's pastoral neighborhood has N farms (2 <= N <= 40 ...

  4. Poj1182 食物链(并查集/带权并查集)

    题面 Poj 题解 这里采用并查集的补集. \(x\)表示同类集合,\(x+n\)表示敌人集合,\(x+n\times2\)表示敌人的敌人集合. 如果当前给出的是一对同类关系,就判断\(x\)是否吃\ ...

  5. POJ 1984 Navigation Nightmare 【经典带权并查集】

    任意门:http://poj.org/problem?id=1984 Navigation Nightmare Time Limit: 2000MS   Memory Limit: 30000K To ...

  6. [poj 2912] Rochambeau 解题报告 (带权并查集)

    题目链接:http://poj.org/problem?id=2912 题目: 题目大意: n个人进行m轮剪刀石头布游戏(0<n<=500,0<=m<=2000) 接下来m行形 ...

  7. poj 1733 Parity game【hash+带权并查集】

    hash一下然后用带权并查集做模2下的前缀和 #include<iostream> #include<cstdio> #include<map> #include& ...

  8. POJ 2492 A Bug's Life 带权并查集

    题意: 思路: mod2 意义下的带权并查集 如果两只虫子是异性恋,它们的距离应该是1. 如果两只虫子相恋且距离为零,则它们是同性恋. (出题人好猥琐啊) 注意: 不能输入一半就break出来.... ...

  9. POJ 2492 A Bug's Life (带权并查集 && 向量偏移)

    题意 : 给你 n 只虫且性别只有公母, 接下来给出 m 个关系, 这 m 个关系中都是代表这两只虫能够交配, 就是默认异性, 问你在给出的关系中有没有与异性交配这一事实相反的, 即同性之间给出了交配 ...

随机推荐

  1. Maven项目报错:Failed to execute goal org.apache.maven.plugins:maven-clean-plugin:2.5:clean (default-clea

    [ERROR] Failed to execute goal org.apache.maven.plugins:maven-clean-plugin:2.5:clean (default-clean) ...

  2. jni 开发

    创建android工程 -> 添加native 函数 添加库之后: 1. 用javah 生成c语言.h头文件时, 在cmd 窗口中cd 到bin/classes 目录下执行下代码无效: java ...

  3. python基础一 day14 复习

    迭代器和生成器迭代器:双下方法 : 很少直接调用的方法.一般情况下,是通过其他语法触发的可迭代的 —— 可迭代协议 含有__iter__的方法('__iter__' in dir(数据))可迭代的一定 ...

  4. 关于POST的请求的问题的汇总

    1)404 解决方式:检查路径,路由问题 2)500 解决方式:1)首先检查代码 2)检查是否是参数未接收到 3)检查是否Content-Type类型导致的参数未收到 4)区分body-raw跟bod ...

  5. 转义字符 & sizeof & strlen

    在定义了数组大小时: sizeof是运算符,表示编译时分配的空间大小,即数组定义的大小,char t[20] = "sfa".sizeof: 20; strlen: 3.在未定义数 ...

  6. java在线聊天项目1.0版 异常处理——开启多个客户端,关闭一个客户端后,在其他客户端中再发出信息会出现异常的处理

    异常一 只开启一个客户端,输入信息后关闭,客户端出现如下异常 根据异常说明 ChatClientFrame客户端117行 提示原因是Socket关闭 分析原因 客户端代码 while (connect ...

  7. mac系统快捷键大全详细介绍(全部)

    对于使用苹果电脑的操作系统的新人来说,快捷键是个很麻烦的问题,要一个个的找到快捷键也不是很容易的问题,今天这篇文章就解决了到处找快捷键的麻烦. 第一种分类:启用快捷键 按下按键或组合键,直到所需的功能 ...

  8. XCode和Cocoa在开发中使用第三方dylib示例

    XCode和Cocoa在开发中使用第三方dylib示例 www.educity.cn   发布者:yukowang   来源:网络转载   发布日期:2014年06月13日      XCode和Co ...

  9. django-ckeditor添加代码功能(codesnippet)

    最近做了一个博客,使用python3+django2.1开发的,后台编辑器和前端显示用的Django-ckeditor富文本编辑器,由于发现没有代码块功能,写上去的代码在前端展示有点乱,于是一顿问度娘 ...

  10. 【OS_Linux】Linux 基本命令整理

    1. 查看目录文件:ls2. 打印当前工作目录:pwd3. 查看文件内容:cat 文件名4. 打开编辑器:vim 文件名 1 2 3 4 5 修改:按Insert键 退出修改模式:按Esc 键 进入输 ...