E - 食物链 (拆点并查集)

题目链接:https://vjudge.net/contest/339425#problem/E

 

思路:

这题原来做的时候用的是种类并查集,但是我忘了。

现在有一个更玄学的做法 

因为说白了就是A B C 三个点之间的关系

那么我就把一个点拆成三个点(也就是开三倍的空间) 分别代表这个点是A B C

然后这个题就成了模拟???

 

 1 #include <math.h>
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <iostream>
 5 #include <algorithm>
 6 #include <string>
 7 #include <string.h>
 8 #include <vector>
 9 #include <map>
10 #include <stack>
11 #include <set>
12 //#include <random>
13 
14 #define LL long long
15 #define INF 0x3f3f3f3f
16 #define ls nod<<1
17 #define rs (nod<<1)+1
18 const int maxn = 3e5 + 10;
19 const double eps = 1e-9;
20 int pre[maxn];
21 
22 void init(int n) {
23     for (int i=0;i<=n;i++) {
24         pre[i] = i;
25     }
26 }
27 
28 int find(int x) {
29     if (pre[x] == x)
30         return x;
31     return pre[x] = find(pre[x]);
32 }
33 
34 void merge(int x,int y) {
35     int rootx = find(x),rooty = find(y);
36     pre[rooty] = rootx;
37 }
38 int main() {
39     int n,k;
40     scanf("%d%d",&n,&k);
41         init(3*n);
42         int d,x,y;
43         int ans = 0;
44         for (int i=1;i<=k;i++) {
45             scanf("%d%d%d",&d,&x,&y);
46             if (x > n || y > n) {
47                 ans++;
48                 continue;
49             }
50             if (d == 1) {
51                 if (find(x) == find(y+n) || find(x) == find(y+2*n) ) {
52                     ans++;
53                     continue;
54                 }
55                 merge(x,y);
56                 merge(x+n,y+n);
57                 merge(x+2*n,y+2*n);
58             }
59             if (d == 2) {
60                 if (find(x) == find(y) || find(x) == find(y+2*n)) {
61                     ans++;
62                     continue;
63                 }
64                 merge(x,y+n);
65                 merge(x+n,y+2*n);
66                 merge(x+2*n,y);
67             }
68         }
69         printf("%d\n",ans);
70     return 0;
71 }

 

posted @ 2019-11-01 20:35  _Ackerman  阅读(361)  评论(0编辑  收藏  举报