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

hdu5354 Bipartite Graph

时间:2015-08-11 00:02:04      阅读:548      评论:0      收藏:0      [点我收藏+]

标签:

  分治+并查集。假设要求[L,mid]的答案,那么很明显,如果一条边的两个端点都>mid的话或者一个端点>mid一个端点<L,说明询问[L,mid]这个区间中任何一点时候,这一条边都是连接的,否则的话递归下去处理。[mid+1,R]同理。

     一个图不是二分图的话说明存在奇环,奇环可以用并查集处理。这里的并查集不使用路径压缩而使用按轶合并。并查集的还原操作可以用一个栈记录每次合并时的具体操作,然后按序还原即可。

  代码

  1 #include<cstdio>
  2 #include<vector>
  3 #define N 300010
  4 using namespace std;
  5 int f[N],d[N];
  6 int n,m,i,dp;
  7 int tt[N],pre[N],p[N],ans[N],flag[N];
  8 int tot,stack[N],a[N],b[N],g[N];
  9 vector<int> vec[N];
 10 void link(int x,int y)
 11 {
 12     dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y;
 13 }
 14 int getfa(int x,int& y)
 15 {
 16     y=0;
 17     while (x!=f[x])
 18     {
 19         y^=g[x]; 
 20         x=f[x];
 21     }
 22     return x;
 23 }
 24 void Union(int x,int y,int &z)
 25 {
 26     int disx,disy;
 27     x=getfa(x,disx);
 28     y=getfa(y,disy);
 29     if (x!=y)
 30     {
 31     if (d[x]>d[y]) x^=y^=x^=y;
 32     f[x]=y;
 33     g[x]=(disx^disy^1);
 34     tot++;stack[tot]=x;
 35     if (d[x]==d[y])
 36     {
 37         flag[tot]=1;
 38         d[y]++;
 39     }
 40     else
 41         flag[tot]=0;
 42     }
 43     else
 44     {
 45         if (disx^disy^1)
 46             z|=1;
 47     }
 48 }
 49 void recover(int x)
 50 {
 51     while (tot>x)
 52     {
 53         if (flag[tot])
 54             d[f[stack[tot]]]--;
 55         f[stack[tot]]=stack[tot];
 56         g[stack[tot]]=0;
 57         tot--;
 58     }
 59 }
 60 void solve(int x,int l,int r,int q)
 61 {
 62     int i,tmp,len,t,Ans;
 63     if (l==r)
 64     {
 65         ans[l]=1-q;
 66         return;
 67     }
 68     int mid=(l+r)>>1;
 69 
 70     vec[2*x].clear();
 71     vec[2*x+1].clear();
 72     tmp=tot;
 73     Ans=q;
 74     len=vec[x].size();
 75     for (i=0;i<len;i++)
 76     {
 77         t=vec[x][i];
 78         if ((a[t]>mid)||((a[t]<l)&&(b[t]>mid)))
 79             Union(a[t],b[t],Ans);
 80         else
 81             vec[2*x].push_back(t);
 82     }
 83     solve(2*x,l,mid,Ans);
 84 
 85     Ans=q;
 86     recover(tmp);
 87     for (i=0;i<len;i++)
 88     {
 89         t=vec[x][i];
 90         if ((b[t]<mid+1)||((a[t]<mid+1)&&(b[t]>r)))
 91             Union(a[t],b[t],Ans);
 92         else
 93             vec[2*x+1].push_back(t);
 94     }
 95     solve(2*x+1,mid+1,r,Ans);
 96 }
 97 int main()
 98 {
 99     int tt;
100     scanf("%d",&tt);
101     while (tt)
102     {
103     tt--;
104     scanf("%d%d",&n,&m);
105     for (i=1;i<=n;i++)
106     {
107         g[i]=0;
108         f[i]=i;
109     }
110     tot=0;
111     vec[1].clear();
112     for (i=1;i<=m;i++)
113     {
114         scanf("%d%d",&a[i],&b[i]);
115         if (a[i]>b[i])
116             a[i]^=b[i]^=a[i]^=b[i];
117         vec[1].push_back(i);
118     }
119     solve(1,1,n,0);
120     for (i=1;i<=n;i++)
121         printf("%d",ans[i]);
122     printf("\n");
123     }
124 }

 

hdu5354 Bipartite Graph

标签:

原文地址:http://www.cnblogs.com/fzmh/p/4719609.html

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