[bzoj4025]二分图_LCT
二分图 bzoj-4025
题目大意:给定一个n个节点的图,m条边,每条边有一个产生时间和一个删除时间,询问所有时间点是否是连通图。
注释:$1\le n\le 10^5$,$1\le m\le 2\cdot 10^5$
想法:好难...
又是一道结论题。开始不知道结论,在那里LCT不知道怎么判二分图... ...
其实就是判每一个时刻有没有奇环... ...硬核题...
紧接着,我们考虑如何维护。
我们先随便弄出一棵生成树,然后我们想维护这样的集合S。S中的任意一条边都会和生成树构成奇环。
有一种情况我们没有办法处理,就是把集合的边加上,然后... ...树边没了,我们还要把集合中的边换成树边,非常麻烦,码量堪忧。
所以,我们要维护最大删除时间生成树,就不会出现以上情况。
最后,附上丑陋的代码... ...
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ls ch[p][0]
#define rs ch[p][1]
#define get(x) (ch[f[x]][1]==x)
#define N 100010
using namespace std;
struct Node
{
int x,y,t1,t2;
}a[N<<1];
int n,f[N<<2],ch[N<<2][2],size[N<<2],w[N<<2],mp[N<<2],rev[N<<2],num[N];
int sum,now;
inline char nc()
{
static char buf[100000],*p1,*p2;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
int ret=0; char ch=nc();
while(!isdigit(ch)) ch=nc();
while(isdigit(ch)) ret=(ret<<3)+(ret<<1)+ch-48,ch=nc();
return ret;
}
inline bool cmp(const Node &a,const Node &b)
{
return a.t1<b.t1;
}
inline void pushup(int p)
{
size[p]=size[ls]+size[rs]+1;
mp[p]=p;
if(w[mp[ls]]<w[mp[p]]) mp[p]=mp[ls];
if(w[mp[rs]]<w[mp[p]]) mp[p]=mp[rs];
}
inline void pushdown(int p)
{
if(!rev[p]) return;
swap(ch[ls][0],ch[ls][1]); swap(ch[rs][0],ch[rs][1]);
rev[ls]^=1; rev[rs]^=1; rev[p]=0;
}
inline bool isroot(int p)
{
return ch[f[p]][0]!=p&&ch[f[p]][1]!=p;
}
void update(int p)
{
if(!isroot(p)) update(f[p]);
pushdown(p);
}
void rotate(int x)
{
int y=f[x],z=f[y],k=get(x);
if(!isroot(y)) ch[z][ch[z][1]==y]=x;
ch[y][k]=ch[x][!k]; f[ch[y][k]]=y;
ch[x][!k]=y; f[y]=x; f[x]=z;
pushup(y); pushup(x);
}
void splay(int x)
{
update(x);
for(int t;t=f[x],!isroot(x);rotate(x))
{
if(!isroot(t)) rotate(get(x)==get(t)?t:x);
}
}
void access(int p)
{
int t=0;
while(p) splay(p),rs=t,pushup(p),t=p,p=f[p];
}
int find(int p)
{
access(p),splay(p);
while(ls) pushdown(p),p=ls;
return p;
}
inline void makeroot(int p)
{
access(p),splay(p);
swap(ls,rs),rev[p]^=1;
}
inline void link(int x,int y)
{
makeroot(x),f[x]=y;
}
inline void cut(int x,int p)
{
makeroot(x),access(p),splay(p);
f[x]=ls=0;pushup(p);
}
inline void split(int x,int y)
{
makeroot(x),access(y),splay(y);
}
void add(int p)
{
int tx=a[p].x,ty=a[p].y,tmp,flag=0;
if(tx==ty&&a[p].t2>now) num[a[p].t2]++,sum++;
else
{
if(find(tx)!=find(ty)) link(p+n,tx),link(ty,p+n);
else
{
split(tx,ty);
if(!((size[ty]>>1)&1)) flag=1;
if(w[mp[ty]]>=a[p].t2) tmp=p;
else tmp=mp[ty]-n,cut(tmp+n,a[tmp].x),cut(tmp+n,a[tmp].y),link(p+n,tx),link(p+n,ty);
if(flag&&a[tmp].t2>now) num[a[tmp].t2]++,sum++;
}
}
}
int main()
{
int m,t,p=1;
n=read(),m=read(),t=read();
for(int i=1;i<=m;i++) a[i].x=read(),a[i].y=read(),a[i].t1=read(),a[i].t2=read();
sort(a+1,a+m+1,cmp);
for(int i=1;i<=n+m;i++) size[i]=1,mp[i]=i;
for(int i=0;i<=n;i++) w[i]=1<<30;
for(int i=1;i<=m;i++) w[i+n]=a[i].t2;
for(int i=0;i<t;i++)
{
now=i;
while(p<=m&&a[p].t1<=i) add(p),p++;
sum-=num[i];
if(sum) puts("No");
else puts("Yes");
}
return 0;
}
小结:LCT就是强。
[bzoj4025]二分图_LCT的更多相关文章
- BZOJ4025 二分图 分治 并查集 二分图 带权并查集按秩合并
原文链接http://www.cnblogs.com/zhouzhendong/p/8683831.html 题目传送门 - BZOJ4025 题意 有$n$个点,有$m$条边.有$T$个时间段.其中 ...
- BZOJ4025 二分图(线段树分治+并查集)
之前学了一下线段树分治,这还是第一次写.思想其实挺好理解,即离线后把一个操作影响到的时间段拆成线段树上的区间,并标记永久化.之后一块处理,对于某个节点表示的时间段,影响到他的就是该节点一直到线段树根的 ...
- [BZOJ4025]二分图(线段树分治,并查集)
4025: 二分图 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2191 Solved: 800[Submit][Status][Discuss] ...
- bzoj4025 二分图
支持加边和删边的二分图判定,分治并查集水之(表示我的LCT还很不熟--仅仅停留在极其简单的模板水平). 由于是带权并查集,并且不能路径压缩,所以对权值(到父亲距离的奇偶性)的维护要注意一下. 有一个小 ...
- bzoj4025二分图(线段树分治 并查集)
/* 思维难度几乎没有, 就是线段树分治check二分图 判断是否为二分图可以通过维护lct看看是否链接出奇环 然后发现不用lct, 并查集维护奇偶性即可 但是复杂度明明一样哈 */ #include ...
- bzoj4025 二分图 [分治,并查集]
传送门 思路 是二分图的充要条件:图没有奇环. 考虑按时间分治,用可撤销并查集维护点到根的距离. 仍然可以用一个小trick把两点连边变成根连边,可以看这里. 每次连边时若不连通则连上,否则判一下有没 ...
- bzoj4025: 二分图 lct
题意:带增删边的查询二分图 题解:因为二分图肯定带奇环,lct维护,每次要加入一条边之前判断会不会构成环,如果会就把最先会删除的边删掉,然后如果是奇环就打个标记,然后把奇环数++,删除的时候,把标记删 ...
- 2018.09.30 bzoj4025: 二分图(线段树分治+并查集)
传送门 线段树分治好题. 这道题实际上有很多不同的做法: cdq分治. lct. - 而我学习了dzyo的线段树分治+并查集写法. 所谓线段树分治就是先把操作分成lognlognlogn个连续不相交的 ...
- BZOJ4025: 二分图【线段树分治】【带撤销的并查集】
Description 神犇有一个n个节点的图.因为神犇是神犇,所以在T时间内一些边会出现后消失.神犇要求出每一时间段内这个图是否是二分图.这么简单的问题神犇当然会做了,于是他想考考你. Input ...
随机推荐
- 02_jni_hello_c函数介绍
介绍NDK平台都有哪些工具.通过NDK这套工具做安卓下的JNI开发. 可能有一些需求更适合通过C去做,有一些功能要通过C去实现.一个安卓程序,它本身还是一个Java应用.有一些功能/方法不通过Java ...
- Linux系统的整体目录结构和文件解析
Linux系统目录结构 使用 ls / 查看系统的文件目录: /:根目录,根目录下一般只存放子目录,不存放文件.在linux系统中所有的文件都挂载该目录下. /bin:命令目录. 存放系统的可执行的二 ...
- Gold Coins
http://poj.org/problem?id=2000 #include<stdio.h> ; int main() { int coin[N]; ,j,k; j = ; k = ; ...
- codevs1225八数码难题(搜索·)
1225 八数码难题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description Yours和zero在研究A*启 ...
- linux 查看内存和cpu
Linux查看CPU和内存使用情况 在系统维护的过程中,随时可能有需要查看 CPU 使用率,并根据相应信息分析系统状况的需要.在 CentOS 中,可以通过 top 命令来查看 CPU 使用状况.运行 ...
- 316 Remove Duplicate Letters 去除重复字母
给定一个仅包含小写字母的字符串,去除重复的字母使得所有字母出现且仅出现一次.你必须保证返回结果是所有可能结果中的以字典排序的最短结果.例如:给定 "bcabc"返回 "a ...
- VS2015环境配置: VS2015 未能正确加载“ResourceManagerPackage”包的问题
启动vs2015专业版时,出现类似于这样的提示框,有好几个,点击是或否,但下次打开还是会出现.笔者也寻找了网上的一些解决办法,例如用vs命令窗口或其他,但都无疾而终,下面提供的这个办法,顺利解决此问题 ...
- iOS CoreData 开发之数据模型关系
接着上一篇,上一篇中,我们简单的实现了一个用户实体,本次添加一个用户信息实体,与用户实体相关联,关系为1:1. 新建一个实体UserInfo:
- JS——for
打印两行星星: <script> for (var i = 0; i < 2; i++) { for (var j = 0; j < 10; j++) { document.w ...
- 【译】x86程序员手册15-5.2页转换
5.2 Page Translation 页转换 In the second phase of address transformation, the 80386 transforms a linea ...