WOJ 18 动态无向图
一开始我是不会写的,后来点开了题解:
无话可说……那就写吧……然而第一发跑成暴力分,后来加了一个优化:就是在询问里面提到过的边都不用再加了。
然后……然后就过了呀……
其实还有面向数据的编程的骚操作……既然卡过了那也没什么好说了。
以前的巨佬们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; }