【BZOJ】4025: 二分圖
阿新 • • 發佈:2018-12-12
題解
lct維護一個結束時間作為邊權的最大生成樹,每次出現奇環就找其中權值最小的那條邊,刪掉的同時還要把它標記上,直到這條邊消失
如果有標記則輸出No
邊權通過建立虛點來維護
程式碼
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define pdi pair<db,int> #define mp make_pair #define pb push_back #define enter putchar('\n') #define space putchar(' ') #define eps 1e-8 #define mo 974711 #define MAXN 300005 //#define ivorysi using namespace std; typedef long long int64; typedef double db; template<class T> void read(T &res) { res = 0;char c = getchar();T f = 1; while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); } res *= f; } template<class T> void out(T x) { if(x < 0) {x = -x;putchar('-');} if(x >= 10) { out(x / 10); } putchar('0' + x % 10); } int N,M,T,cnt; struct E_node { int u,v,s,t; }E[MAXN]; vector<int> a[MAXN],b[MAXN]; bool vis[MAXN]; namespace lct { struct node { int lc,rc,fa,val,minq,siz; bool rev; }tr[MAXN]; #define lc(u) tr[u].lc #define rc(u) tr[u].rc #define fa(u) tr[u].fa #define val(u) tr[u].val #define minq(u) tr[u].minq #define rev(u) tr[u].rev #define siz(u) tr[u].siz void Init() { val(0) = minq(0) = 0x7fffffff; for(int i = 1 ; i <= N ; ++i) { val(i) = minq(i) = T + 2; siz(i) = 1; } } void reverse(int u) { swap(lc(u),rc(u)); rev(u) ^= 1; } void pushdown(int u) { if(rev(u)) { reverse(lc(u)); reverse(rc(u)); rev(u) = 0; } } void update(int u) { minq(u) = val(u); minq(u) = min(minq(u),minq(lc(u))); minq(u) = min(minq(u),minq(rc(u))); siz(u) = 1 + siz(lc(u)) + siz(rc(u)); } bool isRoot(int u) { if(!fa(u)) return true; else return rc(fa(u)) != u && lc(fa(u)) != u; } bool which(int u) { return rc(fa(u)) == u; } void rotate(int u) { int v = fa(u); if(!isRoot(v)) {(v == lc(fa(v)) ? lc(fa(v)) : rc(fa(v))) = u;} fa(u) = fa(v);fa(v) = u; if(u == lc(v)) {lc(v) = rc(u);fa(rc(u)) = v;rc(u) = v;} else {rc(v) = lc(u);fa(lc(u)) = v;lc(u) = v;} update(v); } void Splay(int u) { static int que[MAXN],qr; qr = 0;int x; for(x = u ; !isRoot(x) ; x = fa(x)) que[++qr] = x; que[++qr] = x; for(int i = qr ; i >= 1 ; --i) pushdown(que[i]); while(!isRoot(u)) { if(!isRoot(fa(u))) { if(which(fa(u)) == which(u)) rotate(fa(u)); else rotate(u); } rotate(u); } update(u); } void Access(int u) { for(int x = 0 ; u ; x = u , u = fa(u)) { Splay(u); rc(u) = x; update(u); } } void Makeroot(int u) { Access(u);Splay(u);reverse(u); } void Link(int u,int v) { Makeroot(u);Makeroot(v);Splay(v);fa(v) = u; } void Cut(int u,int v) { Makeroot(u);Access(v);Splay(u); if(rc(u) == v) {rc(u) = 0;fa(v) = 0;update(u);} } int dfs(int u) { if(val(u) == minq(u)) return u; pushdown(u); if(minq(lc(u)) == minq(u)) return dfs(lc(u)); else return dfs(rc(u)); } int Query(int u,int v) { Makeroot(u);Access(v);Splay(u); return dfs(u); } int Query_len(int u,int v) { Makeroot(u);Access(v);Splay(u); return siz(u); } bool Connected(int u,int v) { Makeroot(u);Access(v);Splay(u); int p = u; while(rc(p)) p = rc(p); if(p == v) return true; return false; } } using lct::Link; using lct::Cut; using lct::Makeroot; using lct::Query; using lct::Connected; using lct::Query_len; using lct::tr; void Init() { read(N);read(M);read(T); lct::Init(); for(int i = 1 ; i <= M ; ++i) { read(E[i].u);read(E[i].v);read(E[i].s);read(E[i].t); a[E[i].s + 1].pb(i);b[E[i].t + 1].pb(i); tr[i + N].siz = 1;tr[i + N].val = tr[i + N].minq = E[i].t; } } void Solve() { for(int i = 1 ; i <= T ; ++i) { int s = a[i].size(); for(int j = 0 ; j < s ; ++j) { int k = a[i][j]; if(E[k].u == E[k].v) { if(!vis[k]) {vis[k] = 1;++cnt;} } else if(!Connected(E[k].u,E[k].v)) {Link(k + N,E[k].u);Link(k + N,E[k].v);} else { int t = Query(E[k].u,E[k].v); if(tr[t].val > tr[k + N].val) t = k + N; if((Query_len(E[k].u,E[k].v) / 2) % 2 == 0) { if(!vis[t - N]) {vis[t - N] = 1;++cnt;} } if(t != k + N) { Cut(t,E[t - N].u);Cut(t,E[t - N].v); Link(k + N,E[k].u);Link(k + N,E[k].v); } } } s = b[i].size(); for(int j = 0 ; j < s ; ++j) { int k = b[i][j]; Cut(E[k].u,k + N);Cut(E[k].v,k + N); if(vis[k]) {vis[k] = 0;--cnt;} } if(cnt) puts("No"); else puts("Yes"); } } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Init(); Solve(); return 0; }