ACWing 240. 食物链 带权并查集

Posted wangzhe52xia

tags:

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

题目:

动物王国中有三类动物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和K句话,输出假话的总数。

输入格式

第一行是两个整数N和K,以一个空格分隔。

以下K行每行是三个正整数 D,X,Y,两数之间用一个空格隔开,其中D表示说法的种类。

若D=1,则表示X和Y是同类。

若D=2,则表示X吃Y。

输出格式

只有一个整数,表示假话的数目。

数据范围

1N500001≤N≤50000,
0K1000000≤K≤100000

输入样例:

100 7
1 101 1 
2 1 2
2 2 3 
2 3 3 
1 1 3 
2 3 1 
1 5 5

输出样例:

3


刚开始看的时候觉得并查集好像写不了,就是自己憨憨了,实际上就是取模分为三类,这就是通过这些东西的传递性来确定到祖宗的距离,距离可以分为三类(0,1,2)在取模的情况下

这道题目重点就是想清楚这个取模分类的思路
技术图片
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <string>
 6 #include <map>
 7 #include <vector>
 8 #include <set>
 9 #include <stack>
10 
11 using namespace std;
12 typedef long long ll;
13 
14 const int N  = 5e4 +10;
15 int p[N],d[N];
16 int find(int x)
17 {
18     if(p[x]!=x)
19     {
20         int t = find(p[x]);
21         d[x] += d[p[x]];//从递归的最低层开始更新距离
22         p[x] = t;//路径压缩
23     }
24     return p[x];
25 }
26 int main()
27 {
28     int n,k;
29     cin >> n >> k;
30     for(int i=0;i<=n;i++)
31     {
32         p[i]=i;
33     }
34     int a,x,y;
35     int cun=0;
36     while(k--)
37     {
38         scanf("%d%d%d",&a,&x,&y);
39         if(x>n||y>n)
40         {
41             cun++;
42         }
43         else{
44              if(a==1)
45             {   
46                 int px = find(x);
47                 int py = find(y);
48                 if(px==py&&(d[x] - d[y])%3)cun++;//判断不是同余的距离就不是同一类
49                 else if(px != py)
50                 {
51                     p[px] = py;
52                     d[px] = (d[y] - d[x])%3;
53                 }
54             }
55             else {
56                 int px = find(x);
57                 int py = find(y);
58                 if(px==py&&(d[x] - d[y] -1)%3)cun++;//x吃y,就是在取模的情况下 (d[x] - d[y])%3 =1
59                 else if(px != py)
60                 {
61                     p[px] = py;
62                     d[px] = (d[y] + 1 - d[x])%3;
63                 }
64             }
65         }
66     }
67     cout << cun <<endl;
68 }
View Code

 

 

 

emmm,今天是20200202,是一个比较特殊的日子,确定了今天是自己一个人熬夜补题的日子,自己自律,加油,别再不被重视了,最后一年了,再不努力就再也没有机会了。



以上是关于ACWing 240. 食物链 带权并查集的主要内容,如果未能解决你的问题,请参考以下文章

带权并查集——食物链

带权并查集(含种类并查集)经典模板 例题:①POJ 1182 食物链(经典)②HDU - 1829 A bug's life(简单) ③hihoCoder 1515 : 分数调查(示例代码(代

POJ1182 食物链 —— 带权并查集

poj1182 食物链(带权并查集)

总结一下我理解的带权并查集

POJ 1182 食物链 (带权并查集)