[BZOJ 4025] 二分图
題目傳送-BZOJ4025
題意:
有一張\(n\)個(gè)節(jié)點(diǎn)的無(wú)向圖,其中邊\(i\)在\(s_i\)出現(xiàn),\(e_i\)結(jié)束,并連接著節(jié)點(diǎn)\(x,y\).
并保證\(s_i < e_i \le T\),要求對(duì)于每個(gè)時(shí)間\(t\le T\)輸出此時(shí)的圖是否是二分圖。
\(n\le100000,m\le200000,T\le100000\)
題解:
這是道好題,考到了線段樹(shù)(分治)的思想,聽(tīng)說(shuō)也叫整體二分?
考慮如何做一個(gè)區(qū)間(時(shí)間)[L,R]中的所有答案:
顯然我們只考慮與這個(gè)區(qū)間有交集的邊
分兩種:完全覆蓋這個(gè)區(qū)間,部分覆蓋這個(gè)區(qū)間。
顯然我們可以毫無(wú)顧慮的把第一類的邊都加上
此時(shí)如果已經(jīng)不是二分圖了,那顯然直接GG了
然后對(duì)于其它邊我們只要遞歸下去處理就行了
如何判斷二分圖并支持對(duì)圖的修改:
考慮按秩合并的帶權(quán)并查集,這就不多說(shuō)了
復(fù)雜度的證明:
空間:
觀察發(fā)現(xiàn)每個(gè)區(qū)間的處理需要有一個(gè)邊集
而每條邊最多能在log個(gè)區(qū)間中出現(xiàn)(線段樹(shù)的思想)
那么總共的空間需求就是\(m*log_2T\)的
時(shí)間:
同樣一條邊只能與log個(gè)區(qū)間相關(guān),也就是說(shuō)它只能被刪加log次
所以復(fù)雜度也是\(m*log_2T\)的?
不知道我這樣分析對(duì)不對(duì),貌似@zhouzhendong大佬說(shuō)這是\(log^2\)的
過(guò)程:
已更新至我都錯(cuò)題集-updating
并查集相關(guān)錯(cuò)誤
代碼:
const int N=100010,M=200010; int n,m,T; struct EDGE {int x,y,s,t;inline void in() {read(x); read(y); read(s); read(t); ++s;} }; int ans[N]; int cnt=0; namespace DSU {int val[N],dep[N],fat[N];struct TMP {int fx,fy,dx,dy;};//x merge to y -> dep[fx]<dep[fy]stack<TMP> sta;inline void Init() {for(int i=1;i<=n;i++) fat[i]=i,dep[i]=1,val[i]=0;}inline pii father(int x) {int ret=0;while(x!=fat[x]) ret^=val[x],x=fat[x];return mp(x,ret);}inline bool Merge(int x,int y) {pii tx=father(x),ty=father(y);int fx=tx.F,fy=ty.F,vx=tx.S,vy=ty.S;if(dep[fx]>dep[fy]) swap(fx,fy);int v=1^vx^vy;if(fx==fy) return v==0;sta.push((TMP) {fx,fy,dep[fx],dep[fy]});fat[fx]=fy; val[fx]=v;dep[fy]=max(dep[fy],dep[fx]+1);return true;}inline void Split(int to) {--cnt; assert(cnt>=0);while((int)sta.size()!=to) {// puts("?");assert(!sta.empty());TMP tmp=sta.top(); sta.pop();int fx=tmp.fx,fy=tmp.fy,dx=tmp.dx,dy=tmp.dy;dep[fx]=dx; dep[fy]=dy; fat[fx]=fx; val[fx]=0;}} } vector<EDGE> E; void Solve(int S,int T,vector<EDGE> &E) {assert(S<=T);if((int)E.size()==0) {for(int i=S;i<=T;i++)ans[i]=1;return;}++cnt;vector<EDGE> EL,ER; EL.clear(); ER.clear();int top=DSU::sta.size(),mid=(S+T)>>1;for(int i=0;i<(int)E.size();i++) {EDGE e=E[i];if(e.s<=S && T<=e.t) {if(!DSU::Merge(e.x,e.y)) {// puts("???");for(int j=S;j<=T;j++)ans[j]=0;DSU::Split(top); return;} } else {if(e.s<=mid) EL.push_back(e);if(e.t> mid) ER.push_back(e);}}if(S==T) {ans[S]=1; DSU::Split(top); return;}Solve(S,mid,EL); Solve(mid+1,T,ER);DSU::Split(top); return; } signed main() {// freopen("10.in","r",stdin);// freopen("my.out","w",stdout);mem(ans,-1);read(n); read(m); read(T);DSU::Init();for(int i=1;i<=m;i++) {EDGE e; e.in(); E.push_back(e);}Solve(1,T,E);// for(int i=1;i<=n;i++) printf("%d ",ans[i]);for(int i=1;i<=n;i++) puts(ans[i] ? "Yes" : "No");return 0; } /* 3 3 3 1 2 0 2 2 3 0 3 1 3 1 2 */用時(shí):1h
轉(zhuǎn)載于:https://www.cnblogs.com/functionendless/p/9470217.html
總結(jié)
以上是生活随笔為你收集整理的[BZOJ 4025] 二分图的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 5G及移动边缘计算(MEC)学习笔记(2
- 下一篇: makefile / CMake