这里给出三种生物的关系,吃与同类的关系。由于这三种生物的关系依旧可以形成一个环,A吃B,B吃C,C又吃A。所以可以套种类并查集模版。
题解:链接
这里求的x->y的偏移量,即把x当父节点,y当子节点时,
y的relation,x吃y,则y就被x吃,所以y的relation为1=d-1
代码
#include<iostream> using namespace std; const int maxn = 100000 + 10; int pre[maxn]; int r[maxn]; // 父节点,与父节点的关系。0代表同类,1代表吃父节点,2代表被父节点吃。 int find(int x){ int fx = pre[x]; if(pre[x] != x){ pre[x] = find(pre[x]); //更新关系 r[x] = (r[x] + r[fx]) % 3; } return pre[x]; } int main(){ int n,t,ans; cin >> n >> t; for(int i = 0; i<= n; i++){ pre[i] = i; r[i] = 0; } ans = 0; while(t--){ int x,y,d; cin >> d >> x >> y; int fx = find(x); int fy = find(y); if(x > n || y > n || (d == 2 && x == y)) ans++; // 这里求的x->y的偏移量,即把x当父节点,y当子节点时, //y的relation,x吃y,则y就被x吃,所以y的relation为1=d-1 else if(fx == fy && (r[x] - r[y] + 3) % 3 != d - 1) ans++; else if(fx != fy){ pre[fx] = fy; //合并后转移偏转量 r[fx] = ((d - 1) + r[y] - r[x] + 3) % 3 ; } } cout << ans << endl; return 0; } // return 0;
还有一种对种类并查集的理解(此方法暂补)先上题解+标程
#include <cstdio> inline int read() { char c = getchar(); int n = 0; while (c < '0' || c > '9') { c = getchar(); } while (c >= '0' && c <= '9') { n = (n << 1) + (n << 3) + (c & 15); c = getchar(); } return n; } const int maxN = 100005; int n, m, ans, fa[maxN * 3]; int find(int u) { return fa[u] == u ? u : fa[u] = find(fa[u]); } int main() { n = read(), m = read(); for (int i = 1; i <= n * 3; i++) { fa[i] = i; } for (; m; m--) { int opt = read(), u = read(), v = read(); if (u > n || v > n) { ans++; continue; } if (opt == 1) { if (find(u + n) == find(v) || find(u) == find(v + n)) { ans++; } else { fa[find(u)] = find(v); fa[find(u + n)] = find(v + n); fa[find(u + n + n)] = find(v + n + n); } } else { if (find(u) == find(v) || find(u) == find(v + n)) { ans++; } else { fa[find(u + n)] = find(v); fa[find(u + n + n)] = find(v + n); fa[find(u)] = find(v + n + n); } } } printf("%d ", ans); return 0; }