一开始我是不会写的,后来点开了题解:
无话可说……那就写吧……然而第一发跑成暴力分,后来加了一个优化:就是在询问里面提到过的边都不用再加了。
然后……然后就过了呀……
其实还有面向数据的编程的骚操作……既然卡过了那也没什么好说了。
以前的巨佬们Orz
Code:
#include <cstdio> #include <cstring> using namespace std;const int N = 5005; const int M = 8e5 + 5;int n, m, qn, tot = 0, head[N], ans = 0; int pCnt = 0, id[N], idCnt = 0, ufs[N], cnt[N][N]; bool ex[N][N], men[N][N], vis[N];struct Edge {int to, nxt; } e[M];inline void add(int from, int to) {e[++tot].to = to;e[tot].nxt = head[from];head[from] = tot; }struct Pathway {int u, v; } path[M];struct Query {int type, u, v; } q[M];inline void read(int &X) {X = 0;char ch = 0;int op = 1;for(; ch > '9' || ch < '0'; ch = getchar())if(ch == '-') op = -1;for(; ch >= '0' && ch <= '9'; ch = getchar())X = (X << 3) + (X << 1) + ch - 48;X *= op; }inline void init() {for(int i = 1; i <= n; i++) ufs[i] = i; }int find(int x) {return x == ufs[x] ? x : ufs[x] = find(ufs[x]); }inline void merge(int x, int y) {int fx = find(x), fy = find(y);if(ufs[fx] != fy) ufs[fx] = fy; }void dfs(int x) {vis[x] = 1;for(int i = head[x]; i; i = e[i].nxt) {int y = e[i].to;if(!ex[x][y]) continue;if(vis[y]) continue;dfs(y);} }inline void reCnt() {ans = 0;for(int i = 1; i <= idCnt; i++) vis[i] = 0;for(int i = 1; i <= idCnt; i++)if(!vis[i]) {ans++;dfs(i);} }inline void addEdge(int p) {int u = id[find(q[p].u)], v = id[find(q[p].v)];cnt[u][v]++, cnt[v][u]++;if(!ex[u][v]) {ex[u][v] = ex[v][u] = 1;add(u, v), add(v, u);}// reCnt(); } inline void delEdge(int p) {int u = id[find(q[p].u)], v = id[find(q[p].v)];cnt[u][v]--, cnt[v][u]--;if(!cnt[u][v] && !cnt[v][u]) ex[u][v] = ex[v][u] = 0; // reCnt(); }inline void query(int p) {reCnt();printf("%d\n", ans); }int main() {read(n), read(m);for(int i = 1; i <= m; i++) read(path[i].u), read(path[i].v);read(qn);for(int i = 1; i <= qn; i++) {char op[7];scanf("%s", op);if(op[0] == 'l') {q[i].type = 1, read(q[i].u), read(q[i].v);men[q[i].u][q[i].v] = men[q[i].v][q[i].u] = 1;} if(op[0] == 'c') {q[i].type = 2;read(q[i].u), read(q[i].v);men[q[i].u][q[i].v] = men[q[i].v][q[i].u] = 1;} if(op[0] == 'q') q[i].type = 3;} init();for(int i = 1; i <= m; i++) {if(men[path[i].u][path[i].v]) continue;merge(path[i].u, path[i].v);}for(int i = 1; i <= n; i++) {int nowf = find(i);if(!vis[nowf]) vis[nowf] = 1, id[nowf] = ++idCnt;}/* for(int i = 1; i <= n; i++)printf("%d ", id[find(i)]);printf("\n"); */for(int i = 1; i <= m; i++) {if(!men[path[i].u][path[i].v]) continue;int x = id[find(path[i].u)], y = id[find(path[i].v)];add(x, y), add(y, x);ex[x][y] = ex[y][x] = 1;cnt[x][y]++, cnt[y][x]++;}// reCnt();for(int i = 1; i <= qn; i++) {if(q[i].type == 1) addEdge(i);if(q[i].type == 2) delEdge(i);if(q[i].type == 3) query(i);}return 0; }