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时间内一些边会出现后消失.神犇要求出每一时间段内这个图是否是二分图.这么简 ...
随机推荐
- DrawingCombiner——CAD图纸批量合并软件
DrawingCombiner是一款CAD图纸批量合并软件,可以批量合并多个dwg或dxf文件为单个dwg文件,并可以设置合并后的排列方式. 此程序附属MagicTable(可到依云官网下载:http ...
- 使用signalR创建聊天室。
浏览器支持Html5的情况下,SignalR使用WebSockets,当不支持时SignalR将使用其它技术来实现通讯. 界面如下:左侧包含三种聊天对象,不同的聊天对象会创建不同的对话框. 设计思路参 ...
- perl's Favorite Default: $_
If you omit the control varibele from the beiginning of foreach loop, Perl uses its favrorite defaul ...
- [MFC美化] SkinMagic使用详解1- SkinMagic使用流程
[SkinMagic使用流程] 1.工程配置SkinMagic相关文件 2.初始化SkinMagic皮肤文件,窗体加载皮肤 3.释放皮肤资源 特别声明,SkinMagic要是破解版的,如果不是,可能需 ...
- C#基础--属性
定义一个Book类: namespace ConsoleTest { public class Book { private string _bookIsbn; private string _boo ...
- dplyr 数据操作 常用函数(5)
继续来了解dplyr中的其他有用函数 1.sample() 目的是可以从一个数据框中,随机抽取一些行,然后组成新的数据框. sample_n(tbl, size, replace = FALSE, w ...
- [河南省ACM省赛-第四届] 表达式求值(nyoj 305)
栈的模拟应用: #include<iostream> #include<cstdio> #include<cstring> #include<string&g ...
- Python的加入!
今天有幸领略了Python的风采. 真是好清新>_< 赶紧尝试一下. 好酷. 以后会在项目中使用
- iOS参考工具和资源
图片: Glyphish(图标资源) 资源: SwiftGuide:这份指南汇集了Swift语言主流学习资源,并以开发者的视角整理编排. 27款iOS开源库,让你的开发溜到飞起 创业者的新春礼包—优秀 ...
- linode更换Linux内核教程(独家)
Linode服务器性价比高,最低套餐2G内存,享受每月2TB流量,机房40Gb带宽,每月供需10美元(Linode优惠链接).Linode用户创建vps服务器后,可在后台自定义Linux系统版本,包括 ...