题目链接: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 }