[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 ...
随机推荐
- hibernate基础简单入门1---helloword
1:目录结果 2:实体类(student.java) package com.www.entity; public class Student { private int id; private St ...
- codevs1293送给圣诞夜的极光(bfs)
1293 送给圣诞夜的极光 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 圣诞老人回到了北极圣诞区,已经快到12点了 ...
- 1.1输出“hello,world”
#include<iostream> using namespace std; int main() { cout<<"Hello, World!"< ...
- SQL Sever语言 事务
事务:保障流程的完整执行保证程序某些程序在运行时同时成功同时失败,保证程序的安全性 begin tran --在流程开始的位置加 --此处写SQL语句 if @@error>0 --ERRORS ...
- Laravel5.1学习笔记11 系统架构3 服务提供者
服务提供者 简介 写一个服务提供者 Register注册方法 Boot 方法 注册提供者 缓载提供者 简介 Service providers are the central place of all ...
- 使用淘宝ip地址库开放接口在网站上显示当前用户所在的城市省份网络(完整代码)
查看效果:每天进步网 在网站的页脚 <p>欢迎来自 <?php function GetIpCity() {$realip = '';$unknown = 'unknown';if ...
- Json——转义符
C#后台直接输出Json字符串需要反斜杠“\” context.Response.Write("[{\"Name\": \"wqx\", \" ...
- Windows2008 Server 常规设置及基本安全策略
一.系统及程序 1.屏幕保护与电源 桌面右键--〉个性化--〉屏幕保护程序屏幕保护程序 选择无更改电源设置 选择高性能选择关闭显示器的时间 关闭显示器 选 从不 保存修改 2.安装IIS 管理工具-- ...
- lamlmzhang的新博客开通了,欢迎大家的关注
从这里开始lamlmzhang的java开发之路~!
- HDU_2212_水
DFS Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...