二分图的充要条件是存在奇环,对其线段树分治,用按秩合并并查集维护即可(注意自环)

[bzoj4025]二分图_i++[bzoj4025]二分图_#define_02
 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 }
View Code