二分图 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的更多相关文章

  1. BZOJ4025 二分图 分治 并查集 二分图 带权并查集按秩合并

    原文链接http://www.cnblogs.com/zhouzhendong/p/8683831.html 题目传送门 - BZOJ4025 题意 有$n$个点,有$m$条边.有$T$个时间段.其中 ...

  2. BZOJ4025 二分图(线段树分治+并查集)

    之前学了一下线段树分治,这还是第一次写.思想其实挺好理解,即离线后把一个操作影响到的时间段拆成线段树上的区间,并标记永久化.之后一块处理,对于某个节点表示的时间段,影响到他的就是该节点一直到线段树根的 ...

  3. [BZOJ4025]二分图(线段树分治,并查集)

    4025: 二分图 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2191  Solved: 800[Submit][Status][Discuss] ...

  4. bzoj4025 二分图

    支持加边和删边的二分图判定,分治并查集水之(表示我的LCT还很不熟--仅仅停留在极其简单的模板水平). 由于是带权并查集,并且不能路径压缩,所以对权值(到父亲距离的奇偶性)的维护要注意一下. 有一个小 ...

  5. bzoj4025二分图(线段树分治 并查集)

    /* 思维难度几乎没有, 就是线段树分治check二分图 判断是否为二分图可以通过维护lct看看是否链接出奇环 然后发现不用lct, 并查集维护奇偶性即可 但是复杂度明明一样哈 */ #include ...

  6. bzoj4025 二分图 [分治,并查集]

    传送门 思路 是二分图的充要条件:图没有奇环. 考虑按时间分治,用可撤销并查集维护点到根的距离. 仍然可以用一个小trick把两点连边变成根连边,可以看这里. 每次连边时若不连通则连上,否则判一下有没 ...

  7. bzoj4025: 二分图 lct

    题意:带增删边的查询二分图 题解:因为二分图肯定带奇环,lct维护,每次要加入一条边之前判断会不会构成环,如果会就把最先会删除的边删掉,然后如果是奇环就打个标记,然后把奇环数++,删除的时候,把标记删 ...

  8. 2018.09.30 bzoj4025: 二分图(线段树分治+并查集)

    传送门 线段树分治好题. 这道题实际上有很多不同的做法: cdq分治. lct. - 而我学习了dzyo的线段树分治+并查集写法. 所谓线段树分治就是先把操作分成lognlognlogn个连续不相交的 ...

  9. BZOJ4025: 二分图【线段树分治】【带撤销的并查集】

    Description 神犇有一个n个节点的图.因为神犇是神犇,所以在T时间内一些边会出现后消失.神犇要求出每一时间段内这个图是否是二分图.这么简单的问题神犇当然会做了,于是他想考考你. Input ...

随机推荐

  1. PCB Genesis 外形加内角孔实现方法

    在PCB工程制作CAM时,经常会遇到外形拐角处直角的,而客户对内角是要求,比如最大内角要求R0.5mm或者不接受内角, 但成型方式为铣方式,又不是啤板成型,那怎么处理才可以达到要求效果呢,在这里介绍2 ...

  2. 互斥的数(hash)

    1553 互斥的数  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold     题目描述 Description 有这样的一个集合,集合中的元素个数由给定的N决定, ...

  3. Akka源码分析-Remote-网络链接

    上一篇博客中,我们分析了Akka remote模式下消息发送的过程,但细心的读者一定发现没有介绍网络相关初始化.创建链接.释放链接的过程,本文就介绍一下相关的内容. 网络初始化就离不开ActorSys ...

  4. glances内存分析工具使用

    glances -b 以字节为单位显示网络流量 glances 是一个命令行工具包括如下命令选项:-b:显示网络连接速度 Byte/ 秒-B @IP|host :绑定服务器端 IP 地址或者主机名称- ...

  5. [转]c# 对密码执行散列和 salt 运算方法

    本文转自:http://www.cnblogs.com/CnBlogFounder/archive/2008/07/04/1235690.html 大家对密码执行散列和Salt运算一定不陌生.两个Vi ...

  6. NHibernate系列学习(一)-看看用NH怎么做增速改查

    1.本次所有代码是在一下环境下运行的 学习系统:win8 64bit 开发环境:VS2013,MSSQL2012 NHibernate版本:NHibernate-4.0.3.GA [文章结尾有本次笔记 ...

  7. Maven 学习(1)

    Maven是什么,以及为什么要使用Maven?Maven这个词可以翻译为“知识的积累”,也可以翻译为“专 家”或“内行”.(构建 = 编写源代码+编译源代码+单元测试+生成文档+打包War+部署)Ma ...

  8. Android 使用WebView浏览有声音或者视频的网页,关闭WebView之后,声音或者视频不停止的解决办法

    笔者最近使用Eclipse开发Android移动应用app,其实有一个功能是使用Android系统自带的WebView控件加载Web页面.开发很顺利,浏览也很正常.不过有个比较特殊的一点就是加载的We ...

  9. 03-Servlet 体系结构知识梳理

    一.Servlet体系结构 Java Web应用是基于Servlet规范运行,Servlet顶层类的关联如下图: 从图可看出,Servlet规范基本围绕这几个类运行,其中,与Servlet主动关联的有 ...

  10. html5——应用缓存

    基本概念 1.HTML5中我们可以轻松的构建一个离线(无网络状态)应用,只需要创建一个cache manifest文件 2.可配置需要缓存的资源,网络无连接应用仍可用,本地读取缓存资源,提升访问速度, ...