[bzoj4025]二分图
二分图的充要条件是存在奇环,对其线段树分治,用按秩合并并查集维护即可(注意自环)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 200005 4 #define L (k<<1) 5 #define R (L+1) 6 #define mid (l+r>>1) 7 struct ji{ 8 int fa,son,sh; 9 }vv[N*20]; 10 vector<int>v[N<<2]; 11 int n,m,t,s,xx,yy,x[N],y[N],f[N],d[N],sh[N]; 12 int dis(int k){ 13 if (f[k]==k)return 0; 14 return (d[k]^dis(f[k])); 15 } 16 int find(int k){ 17 if (k==f[k])return k; 18 return find(f[k]); 19 } 20 void update(int k,int l,int r,int x,int y,int z){ 21 if ((x>r)||(l>y))return; 22 if ((x<=l)&&(r<=y)){ 23 v[k].push_back(z); 24 return; 25 } 26 update(L,l,mid,x,y,z); 27 update(R,mid+1,r,x,y,z); 28 } 29 ji add(int x,int y){ 30 s=(dis(x)^dis(y)); 31 x=find(x); 32 y=find(y); 33 if (x==y)return ji{-s,0,0}; 34 if (sh[x]<sh[y])swap(x,y); 35 ji o=ji{x,y,sh[x]}; 36 f[y]=x; 37 d[y]=(s^1); 38 sh[x]=max(sh[x],sh[y]+1); 39 return o; 40 } 41 void clear(ji k){ 42 if (k.fa<=0)return; 43 f[k.son]=k.son; 44 d[k.son]=0; 45 sh[k.fa]=k.sh; 46 } 47 void dfs(int k,int l,int r){ 48 int last=m,flag=1; 49 for(int i=0;i<v[k].size();i++){ 50 vv[++m]=add(x[v[k][i]],y[v[k][i]]); 51 if (!vv[m].fa)flag=0; 52 } 53 if (!flag) 54 for(int i=l;i<=r;i++)printf("No\n"); 55 else 56 if (l==r)printf("Yes\n"); 57 else{ 58 dfs(L,l,mid); 59 dfs(R,mid+1,r); 60 } 61 while (m>last)clear(vv[m--]); 62 } 63 int main(){ 64 scanf("%d%d%d",&n,&m,&t); 65 for(int i=1;i<=n;i++)f[i]=i; 66 for(int i=1;i<=m;i++){ 67 scanf("%d%d%d%d",&x[i],&y[i],&xx,&yy); 68 update(1,1,t,xx+1,yy,i); 69 } 70 m=0; 71 dfs(1,1,t); 72 }