码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 4025: 二分图

时间:2017-12-21 21:44:48      阅读:104      评论:0      收藏:0      [点我收藏+]

标签:clu   树状数组   body   +=   并且   mes   back   cto   vector   

又是一道整体二分的题目,对于每段时间进行操作,判奇环,如果两个点已经联在一起并且是个奇环那么就不是二分图,不同于之前的树状数组,我们要对并查集进行清空操作,因此我们采用按秩合并,将小的合并到大的上面,这样复杂度就变为了O(NlogN)

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int N=300005;
  4 struct edge
  5 {
  6     int u,v,st,ed;
  7 };
  8 struct EDGE
  9 {
 10     int x,y;
 11 }st[N*10];
 12 int n,m,T,fa[N],dis[N],siz[N],top,ans[N];
 13 vector<edge> g;
 14 int getfa(int x){return x==fa[x]?x:getfa(fa[x]);}
 15 int getdis(int x){return x==fa[x]?0:dis[x]^getdis(fa[x]);}
 16 void restore(int b)
 17 {
 18     while(top>b)
 19     {
 20         int fx=st[top].x;
 21         int fy=st[top].y;
 22         top--;
 23         siz[fx]-=siz[fy];
 24         fa[fy]=fy;
 25         dis[fy]=0;
 26     }
 27 }
 28 void solve(int l,int r,vector<edge> w)
 29 {
 30     int s=w.size();
 31     int cur=top;
 32     int mid=l+r>>1;
 33     vector<edge> w1,w2;
 34     for(int i=0;i<s;++i)
 35     {
 36         edge tmp=w[i];
 37         if(tmp.st==l&&tmp.ed==r)
 38         {
 39             int fx=getfa(tmp.u);
 40             int fy=getfa(tmp.v);
 41             int z=getdis(tmp.u)^getdis(tmp.v)^1;
 42             if(fx==fy)
 43             {
 44                 if(z)
 45                 {
 46                     for(int j=l;j<=r;++j) ans[j]=1;
 47                     restore(cur);
 48                     return;
 49                 }
 50             }
 51             else
 52             {
 53                 if(siz[fx]>siz[fy])
 54                 {
 55                     siz[fx]+=siz[fy];
 56                     fa[fy]=fx;
 57                     dis[fy]=z;
 58                     st[++top]=(EDGE){fx,fy};
 59                 }
 60                 else
 61                 {
 62                     siz[fy]+=siz[fx];
 63                     fa[fx]=fy;
 64                     dis[fx]=z;
 65                     st[++top]=(EDGE){fy,fx};
 66                 }
 67             }
 68         }
 69         else if(tmp.ed<=mid) w1.push_back(tmp);
 70         else if(tmp.st>mid) w2.push_back(tmp);
 71         else
 72         {
 73             w1.push_back((edge){tmp.u,tmp.v,tmp.st,mid});
 74             w2.push_back((edge){tmp.u,tmp.v,mid+1,tmp.ed});
 75         }
 76      }
 77      if(l!=r)
 78      {
 79          if(w1.size()) solve(l,mid,w1);
 80          if(w2.size()) solve(mid+1,r,w2);
 81     }
 82     restore(cur);
 83 }
 84 int main()
 85 {
 86     scanf("%d%d%d",&n,&m,&T);
 87     for(int i=1;i<=m;++i)
 88     {
 89         int u,v,sta,ed;
 90         scanf("%d%d%d%d",&u,&v,&sta,&ed);
 91         if(sta==ed) continue;
 92         sta++;
 93         g.push_back((edge){u,v,sta,ed});
 94     }
 95     for(int i=1;i<=n;++i) fa[i]=i,siz[i]=1;
 96     solve(1,T,g);
 97     for(int i=1;i<=T;++i)
 98         if(ans[i]) puts("No");
 99         else puts("Yes");
100     return 0;
101 }

 

BZOJ 4025: 二分图

标签:clu   树状数组   body   +=   并且   mes   back   cto   vector   

原文地址:http://www.cnblogs.com/nbwzyzngyl/p/8082432.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!