/* 这是我第一次碰到真正意义上,因为cin被卡TLE的情况,甚至取消了cin与stdio的同步,也没有丝毫作用...终于明白大家为什么喜欢用scanf胜过用cin了,以后一定要注意!!!还是用scanf为好 如果仍然被卡,就需要考虑下cout换printf了 */ #include <iostream> #include <cstdio> using namespace std; int N, K; const int MAX_K = 1e5 + 20; const int MAX_N = 150010; int T[MAX_K], X[MAX_K], Y[MAX_K]; int par[3 * MAX_N]; void init(int n) { for (int i = 0; i < n; i++) { par[i] = i; } } int find(int x) { return (par[x] == x? x : par[x] = find(par[x])); } void unite(int x, int y) { int u = find(x); int v = find(y); if (u != v) par[u] = v; } bool same(int x, int y) { return find(x) == find(y); } void solve() { // 初始化并查集 // 元素X, X+N, X+2*N分别代表x-A, x-B, x-C init(N * 3); int ans = 0; for (int i = 0; i < K; i++) { int t = T[i], x = X[i] - 1, y = Y[i] - 1; // 把输入变为0,1,2, N-1的范围 // cout << "IN " << i << endl; // 不正确的编号 if (x < 0 || x >= N || y < 0 || y >= N) { ans++; // cout << "wrong " << i << endl; continue; } if (t == 1) //x和y属于同一类的信息 { if ( same(x, y + N) || same(x, y + 2 * N) ) { ans++; // cout << "wrong " << i << endl; } else { unite(x, y); unite(x + N, y + N); unite(x + 2 * N, y + 2 * N); } } else //x吃y的信息 { if ( same(x, y) || same(x, y + 2 * N) ) { ans++; // cout << "wrong " << i << endl; } else { unite(x, y + N); unite(x + N, y + 2 * N); unite(x + 2 * N, y); } } } cout << ans << endl; } int main() { // cin.tie(0); // cin.sync_with_stdio(false); // cin >> N >> K; scanf("%d%d", &N, &K); for (int i = 0; i < K; i++) scanf("%d%d%d", &T[i], &X[i], &Y[i]); // cin >> T[i] >> X[i] >> Y[i]; solve(); return 0; }