hdu_5354_Bipartite Graph(cdq分治+并查集判二分图)
题意:
给你一个由无向边连接的图,问对于每一个点来说,如果删除这个点,剩下的点能不能构成一个二分图。
题解:
如果每次排除一个点然后去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分治+并查集判二分图)的更多相关文章
- [HDU5354]Bipartite Graph(CDQ分治+并查集)
经典动态二分图问题. 考虑solve(l,r)分治成l,mid和mid+1,r.先将区间[mid+1,r]中的点全部加入图中,若此时存在奇环则ans[l..mid]全部为0,否则递归到左边. 递归完左 ...
- 2015多校第6场 HDU 5354 Bipartite Graph CDQ,并查集
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5354 题意:求删去每个点后图是否存在奇环(n,m<=1e5) 解法:很经典的套路,和这题一样:h ...
- 【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$的无向边,每次加入后询问:当前图是否存在一个生成子图,满足所有点的度数都是奇数.如果有,输出这个生成子图 ...
- BZOJ1997 HNOI2010 平面图判定 planar (并查集判二分图)
题意 判断一个存在哈密顿回路的图是否是平面图. n≤200,m≤10000n\le200,m\le10000n≤200,m≤10000 题解 如果一定存在一个环,那么连的边要么在环里面要么在外面.那么 ...
- 2018.09.30 bzoj4025: 二分图(线段树分治+并查集)
传送门 线段树分治好题. 这道题实际上有很多不同的做法: cdq分治. lct. - 而我学习了dzyo的线段树分治+并查集写法. 所谓线段树分治就是先把操作分成lognlognlogn个连续不相交的 ...
- BZOJ_4025_二分图_线段树按时间分治+并查集
BZOJ_4025_二分图_线段树按时间分治+并查集 Description 神犇有一个n个节点的图.因为神犇是神犇,所以在T时间内一些边会出现后消失.神犇要求出每一时间段内这个图是否是二分图.这么简 ...
随机推荐
- IOS GCD图片数据异步下载,下载完成后合成显示
关于GCD使用详解,请看我的上一篇blog:http://www.cnblogs.com/xin-lang/p/6278606.html 前段时间遇到个需要异步下载,下载完成后再组合显示的东西.这里我 ...
- iOS解析crash日志:
iOS解析crash日志:我们在ios开发中会碰到的很多crash问题,如果Debug调试模式的话,我们可以往往很容易的根据log的输出定位到导致crash的原因,但对于已经上线的应用,或者是rele ...
- GTK+2.0学习——第一个GTK程序
#include <gtk/gtk.h> #include <stdio.h> #include <stdlib.h> /* *点击了关闭按钮之后的回调函数 *gt ...
- perl的列表(List)和数组(Array)
If a scalar is the "singular" in Perl, as we described it at the beginning of Chapter 2, t ...
- delphi 程序输出文件夹存放位置
- python json数组对象排序
arr = [{"name": "name_1", "level": 1}, {"name": "name_2 ...
- Linux网络管理之net-tools VS iproute2
查看网卡及IP ifconfig ip link [show] --------- ifconfig -a ip addr show 激活和停止网络接口 ifconfig eth0 up/down i ...
- PHP5.5在windows 安装使用 memcached 服务端的方法以及 php_memcache.dll 下载
PHP5.5 在windows下安装 memcached 的方法 下载服务端资源 http://download.csdn.net/detail/zsjangel/7104727 下载完成后,解压(我 ...
- 移动平台下的Socket几个问题
在页游时代,使用Flash ActionScript 3.0进行开发,as3提供比较简单和健全的socket API.到了手游时代,基于tcp的socket编程遇到了一些棘手的问题.通常情况下手游都要 ...
- 注意Thread.interrupt()方法的真正作用并不是用来中断线程
程序是很简易的.然而,在编程人员面前,多线程呈现出了一组新的难题,如果没有被恰当的解决,将导致意外的行为以及细微的.难以发现的错误. 在本篇文章中,我们针对这些难题之一:如何中断一个正在 ...