• hdu5354 Bipartite Graph


      分治+并查集。假设要求[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("
    ");
    123     }
    124 }
  • 相关阅读:
    组内分享总结
    Java虚拟机内存
    代理 正向代理 反向代理
    Class文件打包成jar并执行
    Oracle 并集交集差集
    Sysstat安装以及简单操作
    树结构列表结构相互转换 js
    nginx配置root和alias的区别
    js call apply 用法
    VS Code配置同步
  • 原文地址:https://www.cnblogs.com/fzmh/p/4719609.html
Copyright © 2020-2023  润新知