题目描述

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

输入

输入数据的第一行是三个整数n,m,T。
第2行到第m+1行,每行4个整数u,v,start,end。第i+1行的四个整数表示第i条边连接u,v两个点,这条边在start时刻出现,在第end时刻消失。

输出

输出包含T行。在第i行中,如果第i时间段内这个图是二分图,那么输出“Yes”,否则输出“No”,不含引号。

样例输入

3 3 3
1 2 0 2
2 3 0 3
1 3 1 2

样例输出

Yes
No
Yes


题解

LCT

考虑二分图的判断方法:没有奇环

那么我们可以按照每条边的出现时间从小到大排序。对于每条边,如果它形成了奇环,那么这个环上所有边的消失时间的最小值之后这个奇环就不复存在。

所以可以使用LCT维护以消失时间为关键字的最大生成树,每次加边时更新这棵生成树,同时如果产生了奇环,就把这个环上的最小消失时间加到桶中。每个时间把该时间的边弹掉,看是否还有其它形成奇环的边,如果有则不是二分图,否则是二分图。

判断是否是奇环可以通过维护size来实现,对于最大生成树,由于使用的是边权,所以需要想办法转化为点权。我们可以在要连接的两个点之间添加虚点,存着这条边的边权,这样边权就转化为了点权。记录一下消失时间最小的边(虚点)是哪个,判断与新边的大小关系,并决定删除哪个即可。

另外,本题卡常= = (其实本机开O2测才11s,不知道bz上怎么就20s++)

需要使用fread读入优化及puts输出才能勉强通过(还好时间没有在最后一页= =)

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 100010
using namespace std;
struct data
{int x , y , t1 , t2;
}a[N << 1];
int n , fa[N << 2] , c[2][N << 2] , si[N << 2] , w[N << 2] , mp[N << 2] , rev[N << 2] , num[N] , 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(ch < '0' || ch > '9') ch = nc();while(ch >= '0' && ch <= '9') ret = (ret << 3) + (ret << 1) + ch - 48 , ch = nc();return ret;
}
bool cmp(data a , data b)
{return a.t1 < b.t1;
}
void pushup(int x)
{si[x] = si[c[0][x]] + si[c[1][x]] + 1;mp[x] = x;if(w[mp[c[0][x]]] < w[mp[x]]) mp[x] = mp[c[0][x]];if(w[mp[c[1][x]]] < w[mp[x]]) mp[x] = mp[c[1][x]];
}
void pushdown(int x)
{if(rev[x]){int l = c[0][x] , r = c[1][x];swap(c[0][l] , c[1][l]) , swap(c[0][r] , c[1][r]);rev[l] ^= 1 , rev[r] ^= 1 , rev[x] = 0;}
}
bool isroot(int x)
{return c[0][fa[x]] != x && c[1][fa[x]] != x;
}
void update(int x)
{if(!isroot(x)) update(fa[x]);pushdown(x);
}
void rotate(int x)
{int y = fa[x] , z = fa[y] , l = (c[1][y] == x) , r = l ^ 1;if(!isroot(y)) c[c[1][z] == y][z] = x;fa[x] = z , fa[y] = x , fa[c[r][x]] = y , c[l][y] = c[r][x] , c[r][x] = y;pushup(y) , pushup(x);
}
void splay(int x)
{update(x);while(!isroot(x)){int y = fa[x] , z = fa[y];if(!isroot(y)){if((c[0][y] == x) ^ (c[0][z] == y)) rotate(x);else rotate(y);}rotate(x);}
}
void access(int x)
{int t = 0;while(x) splay(x) , c[1][x] = t , pushup(x) , t = x , x = fa[x];
}
int find(int x)
{access(x) , splay(x);while(c[0][x]) pushdown(x) , x = c[0][x];return x;
}
void makeroot(int x)
{access(x) , splay(x);swap(c[0][x] , c[1][x]) , rev[x] ^= 1;
}
void link(int x , int y)
{makeroot(x) , fa[x] = y;
}
void cut(int x , int y)
{makeroot(x) , access(y) , splay(y) , fa[x] = c[0][y] = 0 , pushup(y);
}
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(p + n , ty);else{split(tx , ty);if(!((si[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 , i , p = 1;n = read() , m = read() , t = read();for(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(i = 1 ; i <= n + m ; i ++ ) si[i] = 1 , mp[i] = i;for(i = 0 ; i <= n ; i ++ ) w[i] = 1 << 30;for(i = 1 ; i <= m ; i ++ ) w[i + n] = a[i].t2;for(i = 0 ; i < t ; i ++ ){now = i;while(p <= m && a[p].t1 <= i) add(p ++ );sum -= num[i];if(sum) puts("No");else puts("Yes");}return 0;
}

转载于:https://www.cnblogs.com/GXZlegend/p/7148985.html

【bzoj4025】二分图 LCT相关推荐

  1. bzoj4025: 二分图

    这题想不出来. 不浪费时间了. 以后找时间填. --------------------update--------------- 就是判奇环咯 然而LCT我搞不出来.. 是因为对于当前的最大生成树, ...

  2. 【知识点总结】【CSP考前复习】图论大杂烩【未完】

    序言 临近NOIP CSP-J 2019,不由得有些惆怅. 惆怅不是为了别的,主要是觉得从接触信息学竞赛开始,这已经是四个年头了,却一直拿的是二等奖.而今年是我最后的机会.如果不能成功,那自然就是AF ...

  3. 每周记录(4月底停更了qvq)

    1月6日 旋转卡壳 闵可夫斯基和 1月13日 期末复习 1月20日 网络流前4道题 一场失败的期末考试 写寒假作业 bzoj [HNOI2008]明明的烦恼(90分) prufer序列 正睿 画画图 ...

  4. 【BZOJ4025】二分图(可撤销并查集+线段树分治)

    题目: BZOJ4025 分析: 定理:一个图是二分图的充要条件是不存在奇环. 先考虑一个弱化的问题:保证所有边出现的时间段不会交叉,只会包含或相离. 还是不会?再考虑一个更弱化的问题:边只会出现不会 ...

  5. bzoj 4025 二分图——线段树分治+LCT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4025 线段树分治,用 LCT 维护链的长度即可.不过很慢. 正常(更快)的方法应该是线段树分 ...

  6. BZOJ 4025 二分图

    题目大意 给定一个\(n\)个点, \(m\)条边的无向图, 每条边在一定时间范围内存在. 要你判断每个时间点这张图是否为二分图. \(n \le 10^5\) \(m \le 2 \times 10 ...

  7. [BZOJ 4025] 二分图

    题目传送-BZOJ4025 题意: 有一张\(n\)个节点的无向图,其中边\(i\)在\(s_i\)出现,\(e_i\)结束,并连接着节点\(x,y\). 并保证\(s_i < e_i \le ...

  8. 2019.03.01 bzoj2555: SubString(sam+lct)

    传送门 题意简述: 要求在线支持两个操作 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串) 思路: 考虑用lctlctlct来动态维护samsa ...

  9. POJ - 3041 Asteroids 二分图最小点覆盖

    题目链接 二分图一个很重要的定理:看了很多大神的博客表示看不懂为什么,以后再看 最小点覆盖=最大匹配 最小点覆盖就是在二分图里边,选择一个点,将所有与该点相链接的边删去,问最小找多少个点能够把所有的边 ...

最新文章

  1. 【长篇连载】桌面管理演义 第八回 电脑中毒很危险 告警隔离防传染
  2. 微信小程序开发(1)
  3. c语言两个程序合并一起运行,这两个程序如何可以在一起运行
  4. Scala基础教程(六):字符串、数组、集合
  5. 04-JDBC连接MySQL数据库【修改数据】
  6. html设置团偏跟着移动,雷阵雨云团向东偏南移动,北京两地将有强降雨+7级大风+冰雹!...
  7. 安装memcached服务 和 php 安装memcache扩展
  8. Python 大数据分析 淘宝商品销量的关系
  9. css标准流/非标准流 盒子模型
  10. asp.net页面加载时间计算
  11. 怎么得到期刊论文的源代码_帮助这份开放获取期刊计划即将出版的《开放源代码策略》
  12. ft232电路ttl_FT232AM的设计电路及中文资料
  13. 哈希算法(哈希函数)基本
  14. 微信公众号开发工具类
  15. java在win8闪退_win8.1应用闪退
  16. mysql 存储视频_数据库中怎样存储视频?谢谢各位
  17. 2018蓝桥杯 航班时间和乘积尾零
  18. Fiddler证书安装(查看HTTPS)
  19. Prometheus+Grafana监控安装及配置JVM实现企业微信告警
  20. 2020-12-16 今日学习 arraycopy

热门文章

  1. Linux 查看磁盘或文件夹及文件大小
  2. 算法专题 普及组【2008】三3 C++版
  3. Windows Azure移动终端云服务管理(公测版)
  4. java oracle的枚举错误
  5. Weblogic 节点启动
  6. warning C4996: “strcpy”被声明为否决的解决办法
  7. npy一维数组如何对给出的索引进行反选
  8. RedHat5.2下Linux Oracle 10g ASM 安装详细实录-第二篇-ASM安装
  9. 热血沙城-3.2移植-古月-cocos2dx源码
  10. linux系统下PHP无法调用oracle数据库的解决方法