【XSY2469】graph 分治 并查集
题目大意
给你一张\(n\)个点\(m\)条边的无向图,问删去每个点后,原图是不是二分图。
\(n,m\leq 100000\)
题解
一个图是二分图\(\Longleftrightarrow\)该图不存在奇环
可以用并查集,维护每个点到根的距离
如果删除\(x\)点,就要把所有不与\(x\)连接的边加入并查集
考虑分治,对于区间\([l,r]\),我们先把与\([l,mid]\)链接且不与\([mid+1,r]\)链接的边加入并查集,然后递归处理\([mid+1,r]\)。另一边的情况类似。
因为有撤销操作,所以要用按秩合并的并查集
时间复杂度:\(O(m\log^2 n)\)
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
struct list
{
int v[200010];
int t[200010];
int h[100010];
int n;
void clear()
{
memset(h,0,sizeof h);
n=0;
}
void add(int x,int y)
{
n++;
v[n]=y;
t[n]=h[x];
h[x]=n;
}
};
list li;
int f[100010];
int s[100010];
int d[100010];
int find(int x)
{
return f[x]==x?x:find(f[x]);
}
int getdist(int x)
{
return f[x]==x?0:getdist(f[x])^d[x];
}
int e1[100010];
int e2[100010];
int top;
int ans[100010];
int merge(int x,int y)
{
int dist=getdist(x)^getdist(y)^1;
if((x=find(x))==(y=find(y)))
return dist;
top++;
if(s[x]<=s[y])
{
e1[++top]=x;
e2[top]=y;
d[x]=dist;
s[y]+=s[x];
f[x]=y;
}
else
{
e1[++top]=y;
e2[top]=x;
d[y]=dist;
s[x]+=s[y];
f[y]=x;
}
return 0;
}
void solve(int l,int r)
{
if(l==r)
{
ans[l]=1;
return;
}
int mid=(l+r)>>1;
int now=top;
int i,j;
int b=1;
for(i=l;i<=mid&&b;i++)
for(j=li.h[i];j&&b;j=li.t[j])
if(li.v[j]<=mid||li.v[j]>r)
b^=merge(i,li.v[j]);
if(b)
solve(mid+1,r);
else
for(i=mid+1;i<=r;i++)
ans[i]=0;
while(top>now)
{
f[e1[top]]=e1[top];
s[e2[top]]-=s[e1[top]];
top--;
}
now=top;
b=1;
for(i=mid+1;i<=r&&b;i++)
for(j=li.h[i];j&&b;j=li.t[j])
if(li.v[j]<l||li.v[j]>mid)
b^=merge(i,li.v[j]);
if(b)
solve(l,mid);
else
for(i=l;i<=mid;i++)
ans[i]=0;
while(top>now)
{
f[e1[top]]=e1[top];
s[e2[top]]-=s[e1[top]];
top--;
}
}
void solve()
{
top=0;
int n,m;
scanf("%d%d",&n,&m);
int i;
int x,y;
li.clear();
for(i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
li.add(x,y);
li.add(y,x);
}
for(i=1;i<=n;i++)
{
f[i]=i;
s[i]=1;
}
solve(1,n);
for(i=1;i<=n;i++)
putchar(ans[i]+'0');
putchar('\n');
}
int main()
{
// freopen("c.in","r",stdin);
// freopen("c.out","w",stdout);
int t;
scanf("%d",&t);
while(t--)
solve();
return 0;
}
【XSY2469】graph 分治 并查集的更多相关文章
- 【CF576E】Painting Edges 线段树按时间分治+并查集
[CF576E]Painting Edges 题意:给你一张n个点,m条边的无向图,每条边是k种颜色中的一种,满足所有颜色相同的边内部形成一个二分图.有q个询问,每次询问给出a,b代表将编号为a的边染 ...
- 2018.09.30 bzoj4025: 二分图(线段树分治+并查集)
传送门 线段树分治好题. 这道题实际上有很多不同的做法: cdq分治. lct. - 而我学习了dzyo的线段树分治+并查集写法. 所谓线段树分治就是先把操作分成lognlognlogn个连续不相交的 ...
- BZOJ_4025_二分图_线段树按时间分治+并查集
BZOJ_4025_二分图_线段树按时间分治+并查集 Description 神犇有一个n个节点的图.因为神犇是神犇,所以在T时间内一些边会出现后消失.神犇要求出每一时间段内这个图是否是二分图.这么简 ...
- hdu_5354_Bipartite Graph(cdq分治+并查集判二分图)
题目链接:hdu_5354_Bipartite Graph 题意: 给你一个由无向边连接的图,问对于每一个点来说,如果删除这个点,剩下的点能不能构成一个二分图. 题解: 如果每次排除一个点然后去DFS ...
- [HDU5354]Bipartite Graph(CDQ分治+并查集)
经典动态二分图问题. 考虑solve(l,r)分治成l,mid和mid+1,r.先将区间[mid+1,r]中的点全部加入图中,若此时存在奇环则ans[l..mid]全部为0,否则递归到左边. 递归完左 ...
- BZOJ 4025: 二分图 [线段树CDQ分治 并查集]
4025: 二分图 题意:加入边,删除边,查询当前图是否为二分图 本来想练lct,然后发现了线段树分治的做法,感觉好厉害. lct做法的核心就是维护删除时间的最大生成树 首先口胡一个分块做法,和hno ...
- bzoj4025二分图(线段树分治 并查集)
/* 思维难度几乎没有, 就是线段树分治check二分图 判断是否为二分图可以通过维护lct看看是否链接出奇环 然后发现不用lct, 并查集维护奇偶性即可 但是复杂度明明一样哈 */ #include ...
- BZOJ3237:[AHOI2013]连通图(线段树分治,并查集)
Description Input Output Sample Input 4 5 1 2 2 3 3 4 4 1 2 4 3 1 5 2 2 3 2 1 2 Sample Output Connec ...
- BZOJ4025 二分图(线段树分治+并查集)
之前学了一下线段树分治,这还是第一次写.思想其实挺好理解,即离线后把一个操作影响到的时间段拆成线段树上的区间,并标记永久化.之后一块处理,对于某个节点表示的时间段,影响到他的就是该节点一直到线段树根的 ...
随机推荐
- Python全栈开发之路 【第十五篇】:jQuery的介绍和选择器
本节内容 什么是jQuery? write less,do more. jQuery是一个快速,小巧,功能丰富的JavaScript库. 它通过易于使用的API在大量浏览器中运行,使得HTML文档遍历 ...
- 我的微信小程序第三篇(app.json)
前言 端午节回家了,所以好多天没有更新,只想说还是待在家里舒服呀,妈妈各种做好吃的,小侄子侄女各种粘着我在室外玩,导致我三天下来不仅胖了一圈,还黑了一圈,上班第一天有同事就说我晒黑了,哭~~~,为了防 ...
- 蒲公英App开发之检测新版本
https://www.jianshu.com/p/2d3f048511d7 2017.04.17 16:22* 字数 62 阅读 422评论 0喜欢 1 可以在App内部实现检测版本更新并实现安装. ...
- javascript重定向页面并用post方法传递消息
javascript中重定向页面得方法很多,同时能传递消息的也不少:但可用post方法传递的我只找到两种: 第一种方法:用document.write在 JavaScript函数中,用document ...
- Linux基础命令和NAT技术
yum yellowdog updater,modified是一种用python写的基于rpm的管理工具 用于解决rpm包的依赖性 要安装编译工具 yum install gcc 库函数:静态库 ...
- spring aop学习记录
许多AOP框架,比较常用的是Spring AOP 与AspectJ.这里主要学习的Spring AOP. 关于AOP 日志.事务.安全验证这些通用的.散步在系统各处的需要在实现业务逻辑时关注的事情称为 ...
- 如何入门vue之二
学习完指令之后我们需要学习的就是组件. 在学习组件前我们要了解一下 methods 用来处理事件的. computed用来计算属性 他就是类似于data一样只不过是动态的处理数据 里面写的方法当成属 ...
- ES7的新特性
ES7的新特性 ES7 特性: 1.Array.prototype.includes2.Exponentiation Operator(求幂运算) 一,Array.prototype.includes ...
- 一条SQL语句执行得很慢的原因有哪些?(转)
一条 SQL 语句执行的很慢,那是每次执行都很慢呢?还是大多数情况下是正常的,偶尔出现很慢呢?所以我觉得,我们还得分以下两种情况来讨论. 1.大多数情况是正常的,只是偶尔会出现很慢的情况. 2.在数据 ...
- Html5使用canvas作图
以下例子是项目中实际用到的.不足之处请大家指正,设计到画线,写文字,填充,文字旋转. <!DOCTYPE html> <html> <head lang="en ...