[HDU5354]Bipartite Graph(CDQ分治+并查集)
经典动态二分图问题。
考虑solve(l,r)分治成l,mid和mid+1,r。先将区间[mid+1,r]中的点全部加入图中,若此时存在奇环则ans[l..mid]全部为0,否则递归到左边。
递归完左边后将右边的点全部删去,左边点全部加入,按同样的方法处理右边。
判断奇环使用可撤销带权并查集,注意多组数据不要用memset。
#include<cstdio>
#include<algorithm>
#include<cstring>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
using namespace std; const int N=;
int T,n,m,top,cnt,u,v;
int fa[N],sz[N],d[N],ans[N],h[N],nxt[N],to[N];
struct P{ int a,b,c; }s[*N];
struct S{ int x,y; };
void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; } void init(){ cnt=; rep(i,,n) fa[i]=i,sz[i]=,d[i]=,h[i]=; } S get(int x){
if (fa[x]==x) return (S){x,};
S t=get(fa[x]); return (S){t.x,t.y^d[x]};
} void uni(int x,int y){
int t1=get(x).y; x=get(x).x;
int t2=get(y).y; y=get(y).x;
if (sz[x]<sz[y]) swap(x,y);
s[++top]=(P){,y,y}; s[++top]=(P){,x,sz[x]}; s[++top]=(P){,y,};
fa[y]=x; d[y]=t1^t2^; sz[x]+=sz[y];
} void cancel(int x){
if (s[x].a==) fa[s[x].b]=s[x].c;
if (s[x].a==) sz[s[x].b]=s[x].c;
if (s[x].a==) d[s[x].b]=s[x].c;
} void solve(int l,int r){
if (l==r) { ans[l]=; return; }
int mid=(l+r)>>,tmp=top; bool flag=;
rep(u,mid+,r)
for (int i=h[u]; i; i=nxt[i]){
int v=to[i];
if (v>=l && v<=mid) continue;
if (get(u).x!=get(v).x) uni(u,v);
else if (get(u).y==get(v).y) { flag=; break; }
}
if (flag) rep(i,l,mid) ans[i]=; else solve(l,mid);
while (top>tmp) cancel(top--); flag=;
rep(u,l,mid)
for (int i=h[u]; i; i=nxt[i]){
int v=to[i];
if (v>mid && v<=r) continue;
if (get(u).x!=get(v).x) uni(u,v);
else if (get(u).y==get(v).y) { flag=; break; }
}
if (flag) rep(i,mid+,r) ans[i]=; else solve(mid+,r);
while (top>tmp) cancel(top--);
} int main(){
freopen("hdu5354.in","r",stdin);
freopen("hdu5354.out","w",stdout);
for (scanf("%d",&T); T--; ){
scanf("%d%d",&n,&m); init();
rep(i,,m) scanf("%d%d",&u,&v),add(u,v),add(v,u);
solve(,n);
rep(i,,n) printf("%d",ans[i]); puts("");
}
return ;
}
[HDU5354]Bipartite Graph(CDQ分治+并查集)的更多相关文章
- 2015多校第6场 HDU 5354 Bipartite Graph CDQ,并查集
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5354 题意:求删去每个点后图是否存在奇环(n,m<=1e5) 解法:很经典的套路,和这题一样:h ...
- hdu_5354_Bipartite Graph(cdq分治+并查集判二分图)
题目链接:hdu_5354_Bipartite Graph 题意: 给你一个由无向边连接的图,问对于每一个点来说,如果删除这个点,剩下的点能不能构成一个二分图. 题解: 如果每次排除一个点然后去DFS ...
- 【openjudge】C15C Rabbit's Festival CDQ分治+并查集
题目链接:http://poj.openjudge.cn/practice/C15C/ 题意:n 点 m 边 k 天.每条边在某一天会消失(仅仅那一天消失).问每一天有多少对点可以相互到达. 解法:开 ...
- BZOJ 4025: 二分图 [线段树CDQ分治 并查集]
4025: 二分图 题意:加入边,删除边,查询当前图是否为二分图 本来想练lct,然后发现了线段树分治的做法,感觉好厉害. lct做法的核心就是维护删除时间的最大生成树 首先口胡一个分块做法,和hno ...
- 2018.10.01 bzoj3237: [Ahoi2013]连通图(cdq分治+并查集)
传送门 cdq分治好题. 对于一条边,如果加上它刚好连通的话,那么删掉它会有两个大集合A,B.于是我们先将B中禁用的边连上,把A中禁用的边禁用,再递归处理A:然后把A中禁用的边连上,把B中禁用的边禁用 ...
- 【CF603E】Pastoral Oddities cdq分治+并查集
[CF603E]Pastoral Oddities 题意:有n个点,依次加入m条边权为$l_i$的无向边,每次加入后询问:当前图是否存在一个生成子图,满足所有点的度数都是奇数.如果有,输出这个生成子图 ...
- 2018.09.30 bzoj4025: 二分图(线段树分治+并查集)
传送门 线段树分治好题. 这道题实际上有很多不同的做法: cdq分治. lct. - 而我学习了dzyo的线段树分治+并查集写法. 所谓线段树分治就是先把操作分成lognlognlogn个连续不相交的 ...
- hdu5354 Bipartite Graph
分治+并查集.假设要求[L,mid]的答案,那么很明显,如果一条边的两个端点都>mid的话或者一个端点>mid一个端点<L,说明询问[L,mid]这个区间中任何一点时候,这一条边都是 ...
- 【CF576E】Painting Edges 线段树按时间分治+并查集
[CF576E]Painting Edges 题意:给你一张n个点,m条边的无向图,每条边是k种颜色中的一种,满足所有颜色相同的边内部形成一个二分图.有q个询问,每次询问给出a,b代表将编号为a的边染 ...
随机推荐
- Ribbon自带负载均衡策略比较
Ribbon自带负载均衡策略比较 策略名 策略声明 策略描述 实现说明 BestAvailableRule public class BestAvailableRule extends ClientC ...
- 9.1docker容器 跨主机连接
open vswitch 实现跨主机容器连接 准备条件 将本地的网卡 与新建的网桥建立连接 配置 docker 启动项 weave实现跨主机容器连接 null
- a标签的嵌套
1.a标签的嵌套 a标签不能嵌套,若a标签中嵌套了a标签,浏览器会自动添加结束符号,故不能嵌套 2.例子 编辑器中的代码 <a href="#">外层a标签<a ...
- setsockopt 详解
1. closesocket(一般不会立即关闭而经历TIME_WAIT的过程)后想继续重用该socket: BOOL bReuseaddr=TRUE; setsockopt(s,SOL_SOCKET ...
- python基础===两个list之间移动元素
首先我们先了解一下list的几个常用函数: a = [123,456,"tony","jack"] #list中增加元素a.append("www&q ...
- <摘录>Fedora添加国内源和本地源
<摘录>Fedora添加国内源和本地源 http://www.cnblogs.com/hummersofdie/p/3915070.html fedora的软件源信息文件(*.repo)都 ...
- ogre3d环境配置 SDK安装配置及简单事例教程
ogre3d环境配置 SDK安装配置及简单事例教程 http://www.cr173.com/html/22594_1.html ogre3d环境配置 SDK安装配置及简单事例教程 http://ww ...
- clearcase command (linux 常用命令)
http://publib.boulder.ibm.com/infocenter/cchelp/v7r0m0/index.jsp?topic=/com.ibm.rational.clearcase.h ...
- Vim的分屏功能(转)
注:本文属于转载,源地址:http://blog.csdn.net/ithomer/article/details/6035627(博主很牛,欢迎关注) 本篇文章主要教你如何使用 Vim 分屏功能 分 ...
- PHP在变量前面加&是什么意思
比如: <? php $a = 'c' ; $b = & $a ; //表示$b 和 $a 引用了同一个变量 $a = 'abc' ; //这里重置了$a echo $b ; //将输出 ...