博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 1182 食物链 (并查集)
阅读量:7076 次
发布时间:2019-06-28

本文共 2441 字,大约阅读时间需要 8 分钟。

食物链
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 50601   Accepted: 14786

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

100 71 101 1 2 1 22 2 3 2 3 3 1 1 3 2 3 1 1 5 5

Sample Output

3 草泥马我终于把这题A了!!!!!! 当时我看完c primer plus的时候,心中最大的感觉就是真正优秀的教材就是能让傻子都能学懂,依照这样的观念来看———网上的大部分题解写得TM就跟屎一样!!!写不清楚你至少别误人子弟,推个公式推半天结果全是找规律没任何数学证明,乱七八糟写一堆浪费别人时间,要不是找到了那篇思路清晰的不知道还要耗几天! 良心声明:我没精力也没本事把这题讲清楚,下面的过程纯属自用,留着以后自己来看,所以只求我自己能看懂,不建议参考,但是强烈推荐参考这篇: http://blog.csdn.net/niushuai666/article/details/6981689,清晰的说明了网上那堆乱七八糟的公式是如何用数学推出来的! R[i]的意思是  i的父节点 -> i  的关系,绝对不能反。 STEP 1:
 
这一步要先将x的父节点更新成最上面这个,然后再更新R[x]的值。 STEP 2: 所以要将右子树挂到左子树上去,那么右子树的根节点的关系值就要更新成它与左子树根节点的关系,从第二个图上可以看出来,新的R[fy] =(R[x] + v + (3 - R[y])) % 3,最后模3是为了确保关系值始终在0-2的范围内。
1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 using namespace std;14 15 const int SIZE = 50005;16 int FATHER[SIZE],R[SIZE];17 int N,M,ANS;18 19 void ini(void);20 int find_father(int);21 void unite(int,int,int);22 int main(void)23 {24 int x,y,v;25 26 scanf("%d%d",&N,&M);27 ini();28 while(M --)29 {30 scanf("%d%d%d",&v,&x,&y);31 if(x > N || y > N || (x == y && v == 2))32 ANS ++;33 else34 unite(x,y,v);35 }36 printf("%d\n",ANS);37 38 return 0;39 }40 41 void ini(void)42 {43 ANS = 0;44 for(int i = 1;i <= N;i ++)45 {46 FATHER[i] = i;47 R[i] = 0;48 }49 }50 51 int find_father(int n)52 {53 if(n == FATHER[n])54 return n;55 int temp = FATHER[n];56 FATHER[n] = find_father(FATHER[n]);57 R[n] = (R[temp] + R[n]) % 3;58 59 return FATHER[n];60 }61 62 void unite(int x,int y,int v)63 {64 int fx = find_father(x);65 int fy = find_father(y);66 67 if(fx == fy)68 {69 if((3 - R[x] + R[y]) % 3 != v - 1)70 ANS ++;71 return ;72 }73 74 FATHER[fy] = fx;75 R[fy] = (R[x] + v - 1 + 3 - R[y]) % 3;76 }

 

 

转载于:https://www.cnblogs.com/xz816111/p/4538466.html

你可能感兴趣的文章
Shell理论学习(一)
查看>>
phpcms开发之模板语法规则
查看>>
CST UTC
查看>>
因为看见,所以发现:QBotVariant谢绝落幕
查看>>
我的友情链接
查看>>
让Apache支持shtml实现include文件解析的配置方法
查看>>
软件测试学习:检查产品说明书
查看>>
linux 防火墙
查看>>
mysql事务提交模式
查看>>
word search 此题若会,所有dfs矩阵全会
查看>>
ASP.NET Cache的一些总结2
查看>>
JAVA中易出错的小问题(二)
查看>>
asp.net 用正则表达式过滤内容中的电话,qq,email
查看>>
1109 Group Photo
查看>>
Flutter插件开发之APK自动安装
查看>>
创建本地CM 离线服务器
查看>>
PHP数组操作——取数组最后一个值
查看>>
springboot集成swagger2
查看>>
node.js学习之流解析(一)
查看>>
YxdIOCP (DIOCP修改版)
查看>>