题意是给定一颗森林,然后每次都可以删除一条边,或者询问某两个点是否连通。
如果顺着做是不行的。因为并查集路径压缩了,是删不了边的,(据说不路径压缩能AC,)
所以考虑逆向操作。首先不能把已经删除了的边加进去森林里面,先处理出最终状态,然后倒着模拟,就能把删边操作等价于变成加边操作了。注意有一点坑得地方就是,多次删除某一条边,那么你只能在第一次删除这条边的地方把这条边建立起来,
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <assert.h> #define IOS ios::sync_with_stdio(false) using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; #include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> #include <bitset> const int maxn = 20000 + 20; int fa[maxn], baba[maxn]; int tofind(int u) { if (fa[u] == u) return u; else return fa[u] = tofind(fa[u]); } void tomerge(int x, int y) { if (x == 0) return; if (y == 0) while(1); x = tofind(x); y = tofind(y); fa[y] = x; } struct Node { char ch; int a, b; }query[maxn]; bool ans[maxn]; int del[maxn]; void init() { for (int i = 1; i <= maxn - 2; ++i) fa[i] = i; memset(del, false, sizeof del); memset(ans, false, sizeof ans); } int f; void work() { init(); int n, q; cin >> n >> q; for (int i = 1; i <= n; ++i) { cin >> baba[i]; } for (int i = 1; i <= q; ++i) { char str[22]; cin >> str; query[i].ch = str[0]; if (str[0] == 'C') { cin >> query[i].a; if (del[query[i].a]) continue; else del[query[i].a] = i; } else { cin >> query[i].a >> query[i].b; } } for (int i = 1; i <= n; ++i) { if (del[i]) continue; tomerge(baba[i], i); } for (int i = q; i >= 1; --i) { if (query[i].ch == 'C') { if (del[query[i].a] != i) continue; tomerge(baba[query[i].a], query[i].a); continue; } int x = tofind(query[i].a); int y = tofind(query[i].b); if (x == y) { ans[i] = true; } } printf("Case #%d: ", ++f); for (int i = 1; i <= q; ++i) { if (query[i].ch == 'C') continue; if (ans[i]) { printf("YES "); } else printf("NO "); } } int main() { #ifdef local freopen("data.txt", "r", stdin); // freopen("data.txt", "w", stdout); #endif int t; scanf("%d", &t); while (t--) work(); return 0; }
1
2 1
0 0
Q 1 2
2 1
0 0
Q 1 2
1
4 3
0 1 2 2
C 2
Q 2 1
C 2
4 3
0 1 2 2
C 2
Q 2 1
C 2
1
2 3
0 0
Q 1 2
C 1
C 2
2 3
0 0
Q 1 2
C 1
C 2