题目链接:hdu_5354_Bipartite Graph

题意:

给你一个由无向边连接的图,问对于每一个点来说,如果删除这个点,剩下的点能不能构成一个二分图。

题解:

如果每次排除一个点然后去DFS判是否为二分图,那肯定会超时。

我们可以知道,删除其中一个点,对其他好多的边都不会有影响,所以我们可以将其他点的边先加进去,然后来判断一个区间的点是否可行。

这就和cdq分治的思想差不多。我们令cdq(l,r)表示解决l到r区间的答案。然后通过并查集来判断已经加入的点是否为二分图。

并查集在判二分图的时候不能路径压缩,因为我们在cdq过程中会还原并查集的结构。

这里要注意,如果在更新[l,mid]时候,[mid+1,r]只要不能构成二分图,那么[l,mid]的答案就全部都是0,然后就是在并查集合并的时候要以节点多的树为跟,这样才不会T。

 #include<bits/stdc++.h>
#define F(i,a,b) for(int i=a;i<=b;i++)
using namespace std; const int N=1e5+;
int t,n,m,ed,g[N],v[N*],nxt[N*],rk[N],col[N],top,fa[N];
char ans[N];
struct node
{
int u,v,colu,colv,fau,fav,rku,rkv;
node(){}
node(int _u,int _v,int _colu,int _colv,int _fau,int _fav,int _rku,int _rkv):
u(_u),v(_v),colu(_colu),colv(_colv),fau(_fau),fav(_fav),rku(_rku),rkv(_rkv){}
}S[N],tmp; void init(){ed=top=,ans[n+]=;F(i,,n)g[i]=,rk[i]=col[i]=,fa[i]=i;}
void adg(int x,int y){v[++ed]=y,nxt[ed]=g[x],g[x]=ed;} inline int find_fa(int x){return fa[x]==x?x:find_fa(fa[x]);}
inline int find_col(int x)
{
if(fa[x]==x)return col[x];
return col[x]?find_col(fa[x]):!find_col(fa[x]);
} int merge(int u,int v)
{
int fa_u=find_fa(u),fa_v=find_fa(v);
int col_u=find_col(u),col_v=find_col(v);
if(fa_u==fa_v)
{//如果同根并且同色,又有这条边,该图肯定不是二分图
if(col_u==col_v)return ;
return ;
}
int rt,son;
if(rk[fa_u]<rk[fa_v])rt=fa_v,son=fa_u;else rt=fa_u,son=fa_v;//以大树为根
S[++top]=node(rt,son,col[rt],col[son],fa[rt],fa[son],rk[rt],rk[son]);
if(col_u==col_v)col[son]^=;//如果要合并的两个点的颜色相同,那么将要作为儿子的点改变颜色
fa[son]=rt,rk[rt]+=rk[son];
return ;
} void back(int pre)//还原并查集
{
while(top>pre)
{
tmp=S[top--];
int u=tmp.u,v=tmp.v;
col[u]=tmp.colu,col[v]=tmp.colv;
fa[u]=tmp.fau,fa[v]=tmp.fav;
rk[u]=tmp.rku,rk[v]=tmp.rkv;
}
} int unite(int l,int r,int a,int b)
{
F(j,l,r)for(int i=g[j];i;i=nxt[i])
{
if(a<=v[i]&&v[i]<=b)continue;//只合并[l,r]区间的点
if(!merge(j,v[i]))return ;
}
return ;
} void cdq(int l=,int r=n,int flag=)
{
if(l==r){ans[l]=flag+'';return;}
int mid=l+r>>,pre=top,now=flag&&unite(mid+,r,l,mid);
cdq(l,mid,now),back(pre);
now=flag&&unite(l,mid,mid+,r);
cdq(mid+,r,now),back(pre);
} int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
init();
F(i,,m)
{
int x,y;
scanf("%d%d",&x,&y);
adg(x,y),adg(y,x);
}
cdq(),printf("%s\n",ans+);
}
return ;
}

hdu_5354_Bipartite Graph(cdq分治+并查集判二分图)的更多相关文章

  1. [HDU5354]Bipartite Graph(CDQ分治+并查集)

    经典动态二分图问题. 考虑solve(l,r)分治成l,mid和mid+1,r.先将区间[mid+1,r]中的点全部加入图中,若此时存在奇环则ans[l..mid]全部为0,否则递归到左边. 递归完左 ...

  2. 2015多校第6场 HDU 5354 Bipartite Graph CDQ,并查集

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5354 题意:求删去每个点后图是否存在奇环(n,m<=1e5) 解法:很经典的套路,和这题一样:h ...

  3. 【openjudge】C15C Rabbit's Festival CDQ分治+并查集

    题目链接:http://poj.openjudge.cn/practice/C15C/ 题意:n 点 m 边 k 天.每条边在某一天会消失(仅仅那一天消失).问每一天有多少对点可以相互到达. 解法:开 ...

  4. BZOJ 4025: 二分图 [线段树CDQ分治 并查集]

    4025: 二分图 题意:加入边,删除边,查询当前图是否为二分图 本来想练lct,然后发现了线段树分治的做法,感觉好厉害. lct做法的核心就是维护删除时间的最大生成树 首先口胡一个分块做法,和hno ...

  5. 2018.10.01 bzoj3237: [Ahoi2013]连通图(cdq分治+并查集)

    传送门 cdq分治好题. 对于一条边,如果加上它刚好连通的话,那么删掉它会有两个大集合A,B.于是我们先将B中禁用的边连上,把A中禁用的边禁用,再递归处理A:然后把A中禁用的边连上,把B中禁用的边禁用 ...

  6. 【CF603E】Pastoral Oddities cdq分治+并查集

    [CF603E]Pastoral Oddities 题意:有n个点,依次加入m条边权为$l_i$的无向边,每次加入后询问:当前图是否存在一个生成子图,满足所有点的度数都是奇数.如果有,输出这个生成子图 ...

  7. BZOJ1997 HNOI2010 平面图判定 planar (并查集判二分图)

    题意 判断一个存在哈密顿回路的图是否是平面图. n≤200,m≤10000n\le200,m\le10000n≤200,m≤10000 题解 如果一定存在一个环,那么连的边要么在环里面要么在外面.那么 ...

  8. 2018.09.30 bzoj4025: 二分图(线段树分治+并查集)

    传送门 线段树分治好题. 这道题实际上有很多不同的做法: cdq分治. lct. - 而我学习了dzyo的线段树分治+并查集写法. 所谓线段树分治就是先把操作分成lognlognlogn个连续不相交的 ...

  9. BZOJ_4025_二分图_线段树按时间分治+并查集

    BZOJ_4025_二分图_线段树按时间分治+并查集 Description 神犇有一个n个节点的图.因为神犇是神犇,所以在T时间内一些边会出现后消失.神犇要求出每一时间段内这个图是否是二分图.这么简 ...

随机推荐

  1. CentOS 7安装nginx

    CentOS 7安装nginx 参考网上其他文章做的 安装Nginx 我们从nginx官方的RPM源来安装一个预构建的稳定版本的nginx包. rpm --import http://nginx.or ...

  2. java 报表到excel

    现加个jar包 http://pan.baidu.com/s/1boe5kXh   vfp8 然后代码 package makeReportToExcel; import java.io.File; ...

  3. 脚本录制--html模式和url模式

    设置位置:tool--recording options-recording 1.html模式--默认---结果较简单 脚本采用html页面的形式来展示,优点:容易维护.容易理解 2.url模式--- ...

  4. lua中的面向对象编程

    简单说说Lua中的面向对象 Lua中的table就是一种对象,看以下一段简单的代码: 上述代码会输出tb1 ~= tb2.说明两个具有相同值得对象是两个不同的对象,同时在Lua中table是引用类型的 ...

  5. dirty cow exp

    公司搞底层的改了一下,说做到了几个不死机 /* * (un)comment correct payload first (x86 or x64)! * * $ gcc cowroot.c -o cow ...

  6. iOS APP中Versions和build版本区别

    version是app发布时用户看到的版本号. build的为了方便开发者多次提交binary, 比如被苹果reject后. 例如,第一次提交version和build都是1.0. 假如审核没过,那么 ...

  7. XML+AJAX

  8. SQL 默认数据库被误删

    我今天也遇到了,自己解决了.这是我总结的:(不管这帖子沉到哪里了) 删除了SQL服务器默认数据库,无法连接服务器,用户[]登录失败. 1,使用管理员账户修改此用户的默认数据库.    企业管理器,展开 ...

  9. 生成 Qt 文档

    个人总结    从命令行进入Qt安装目录     设置环境变量     set path=D:/mingw32/bin;D:/Qt/5.0.0/qtbase/bin;D:/icu/bin;D:/icu ...

  10. 一步步优化JVM一:概述、方法及需求

    现代JVM是一个具有灵活适应各种应用能力的软件,尽管很多应用能够在JVM的默认配置下运行良好,但是有些应用还是需要优化JVM配置以达到其性能要求.由于各种各样的应用能够运行在现在JVM上面,所以大量的 ...