题目链接: 食物链
思路
首先自然是排除假话2和假话3
然后就是用val[i]代表该节点和根节点之间的关系了。注意 (sum + val[b] - val[a])可能为负数 所以里面要+3. 最后的判断我直接用的多个if,懒得去想简单的了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| #include <iostream> #include <algorithm> #include <stdio.h> #include <string> using namespace std; int val[100001],f[100001]; int Find(int x) { if(x != f[x]) { int t = f[x]; f[x] = Find(f[x]); val[x] = (val[x] + val[t]) % 3; } return f[x]; } int main() { int N, num, M, t, a, b, caser = 1,sum; scanf("%d %d",&N,&M); for(int i = 1; i <= N; ++i) { f[i] = i; val[i] = 0; } int flag = 0; for(int i = 1; i <= M; ++i) { scanf("%d %d %d",&num,&a,&b); if(a > N || b > N || (num == 2 && a == b)) { flag ++; continue; } if(num == 1) { sum = 0; } else if(num == 2) { sum = 1; } int fa = Find(a); int fb = Find(b); if(fa != fb) { f[fa] = fb; val[fa] = (sum + val[b] - val[a] + 3) % 3; } else { if(num == 1 && val[a] != val[b]) flag++; else if(num == 2 && val[a] == 0 && val[b] != 2) flag++; else if(num == 2 && val[a] == 1 && val[b] != 0) flag ++; else if(num == 2 && val[a] == 2 && val[b] != 1) flag ++; } } if(flag) cout << flag << endl; }
|