【bzoj3237】[Ahoi2013]連通圖
阿新 • • 發佈:2018-11-19
題目連結
太神辣,想我這種zz根本想不到
這裡就不寫了(其實是我懶
程式碼:
#include<cstdio> #include<cmath> #include<queue> #include<stack> #include<vector> #include<algorithm> #include<cstring> using namespace std; typedef long long LL; const int maxn = 200010; const int maxs = 20 * 2 * maxn; struct data{ int u,dep,fa; }stk[maxs]; struct edge{ int u,v; }e[maxn]; int n,m,q,top,maxtop,p[maxn][10],c[maxn],ans[maxn]; int fa[maxn],dep[maxn]; int vis[maxn]; inline int getint() { int ret = 0,f = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); } while (c >= '0' && c <= '9') ret = ret * 10 + c - '0',c = getchar(); return ret * f; } inline int find(int u) { return fa[u] == u ? u : find(fa[u]); } inline void LetBeOne(int u,int v) { if (u == v) return; stk[++top] = (data){u,dep[u],fa[u]}; stk[++top] = (data){v,dep[v],fa[v]}; if (dep[u] < dep[v]) swap(u,v); if (dep[u] == dep[v]) dep[u]++; fa[v] = u; } inline void recover(int now) { while (top != now) { int u = stk[top].u; fa[u] = stk[top].fa; dep[u] = stk[top].dep; top--; } } inline void LetBe(int l,int r,int x) { for (int i = l; i <= r; i++) for (int j = 1; j <= c[i]; j++) vis[p[i][j]] = x; } inline void Link(int l,int r) { for (int i = l; i <= r; i++) for (int j = 1; j <= c[i]; j++) if (!vis[p[i][j]]) LetBeOne(find(e[p[i][j]].u),find(e[p[i][j]].v)); } inline void solve(int l,int r) { if (l == r) { for (int i = 1; i <= c[l]; i++) if (find(e[p[l][i]].u) != find(e[p[l][i]].v)) {ans[l] = 0; return;} ans[l] = 1; return; } // printf("%d\n",top); int mid = l + r >> 1,now = top; LetBe(l,mid,1); Link(mid + 1,r); LetBe(l,mid,0); solve(l,mid); recover(now); LetBe(mid + 1,r,1); Link(l,mid); LetBe(mid + 1,r,0); solve(mid + 1,r); recover(now); } int main() { #ifdef AMC freopen("AMC1.txt","r",stdin); freopen("AMC2.txt","w",stdout); #endif n = getint(); m = getint(); for (int i = 1; i <= m; i++) e[i].u = getint() , e[i].v = getint(); q = getint(); for (int i = 1; i <= q; i++) { c[i] = getint(); for (int j = 1; j <= c[i]; j++) p[i][j] = getint(); } for (int i = 1; i <= n; i++) fa[i] = i; LetBe(1,q,1); for (int i = 1; i <= m; i++) if (!vis[i]) LetBeOne(find(e[i].u),find(e[i].v)); LetBe(1,q,0); solve(1,q); for (int i = 1; i <= q; i++) puts(ans[i] ? "Connected" : "Disconnected"); return 0; }