BZOJ 4025: 二分图

4025: 二分图

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 870  Solved: 333
[Submit][Status][Discuss]

Description

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

Input

输入数据的第一行是三个整数n,m,T。

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

Output

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

Sample Input

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

Sample Output

Yes
No
Yes

HINT

样例说明:

0时刻,出现两条边1-2和2-3。

第1时间段内,这个图是二分图,输出Yes。

1时刻,出现一条边1-3。

第2时间段内,这个图不是二分图,输出No。

2时刻,1-2和1-3两条边消失。

第3时间段内,只有一条边2-3,这个图是二分图,输出Yes。

数据范围:

n<=100000,m<=200000,T<=100000,1<=u,v<=n,0<=start<=end<=T。

Source

[Submit][Status][Discuss]

CDQ分治 + 可回溯的并查集

 1 #include <bits/stdc++.h>
 2   const int siz = 2000005;
 3   int n, m, tim, fa[siz], sz[siz], bk[siz], tot, ans[siz];
 4   struct edge { int x, y, s, t; }e[siz];
 5   inline bool cmp1(const edge &a, const edge &b) {
 6     return a.s == b.s ? a.t < b.t : a.s < b.s;
 7 } inline bool cmp2(const edge &a, const edge &b) {
 8     return a.t == b.t ? a.s < b.s : a.t < b.t;
 9 } inline int find(int u) {
10     while (fa[u] != u)u = fa[u]; return u;
11 } inline void add(int a, int b) {
12     int A = find(a), B = find(b);
13     if (sz[A] > sz[B])fa[B] = A, sz[A] += sz[B], bk[++tot] = B;
14     else fa[A] = B, sz[B] += sz[A], bk[++tot] = A;
15 } inline bool adde(int a, int b) {
16     --a, --b; add(a << 1, b << 1 | 1), add(a << 1 | 1, b << 1); return find(a << 1) == find(a << 1 | 1);
17 } inline void rec(int a) {
18     sz[fa[a]] -= sz[a]; fa[a] = a;
19 } void solve(int L, int R, int l, int r) {
20     for (int i = l; i <= r; ++i)if (e[i].s <= L && e[i].t >= R) { if (adde(e[i].x, e[i].y)) {
21         for (int j = L; j <= R; ++j)ans[j] = 1; return; } else std::swap(e[i--], e[r--]); }
22     if (L == R)return; int top = tot, mid = (L + R) >> 1;
23     { std::sort(e + l, e + r + 1, cmp1); int t = l; while (t <= r && e[t].s <= mid)++t; solve(L, mid, l, t - 1); while (tot > top)rec(bk[tot--]); }
24     { std::sort(e + l, e + r + 1, cmp2); int t = r; while (t >= l && e[t].t >= mid + 1)--t; solve(mid + 1, R, t + 1, r); while (tot > top)rec(bk[tot--]); }
25 } signed main(void) {
26     scanf("%d%d%d", &n, &m, &tim);
27     for (int i = 1; i <= 2 * n; ++i)fa[i] = i, sz[i] = 1;
28     for (int i = 1; i <= m; ++i)scanf("%d%d%d%d", &e[i].x, &e[i].y, &e[i].s, &e[i].t), ++e[i].s;
29     solve(1, tim, 1, m); for (int i = 1; i <= tim; ++i)puts(ans[i] ? "No" : "Yes");
30 }

@Author: YouSiki

时间: 2024-10-11 01:10:23

BZOJ 4025: 二分图的相关文章

BZOJ 4025 二分图(时间树+并查集)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4025 [题目大意] 给出一张图,有些边只存在一段时间,问在一个每个时间段, 这张图是否是二分图 [题解] 判断是否是二分图只要判断是否存在奇环即可, 我们对时间进行分治,在操作树上加删边, 保留涵盖时间区间的有效操作,将剩余操作按时间划分到两端的子树, 退出子树的时候撤销加边操作. 对于判断奇环,我们用并查集维护每个点与标兵的相对距离的奇偶性即可, 由于需要撤销操作,我们放弃对并查集

BZOJ 4025 二分图 分治+并查集

题目大意:给定一张n个点的图,有m条边,T个时间段,每条边只存在于(st,ed]这些时间段,求每个时间段内这个图是否是二分图 分治并查集大法好 定义Solve(x,y,E)为当前处理的区间为[x,y],E为所有存在时间为[x,y]的子集的边的集合 那么对于E中的每一条边(u,v),讨论: 若当前边的存在时间为[x,y],则在并查集上判断是否出现奇环 如果出现,[x,y]内的所有时刻都一定不是二分图,输出答案即可 如果不出现,在并查集中连接(u,v) 否则判断存在时间和mid的关系讨论扔进左区间还

Bzoj 4950 (二分图最大匹配)

Description 那是春日里一个天气晴朗的好日子,你准备去见见你的老朋友Patrick,也是你之前的犯罪同伙.Patrick在编程竞赛 上豪赌输掉了一大笔钱,所以他需要再干一票.为此他需要你的帮助,虽然你已经金盆洗手了.你刚开始很不情愿, 因为你一点也不想再回到那条老路上了,但是你觉得听一下他的计划也无伤大雅.在附近的一个仓库里有一批货物, 包含一些贵重的消费性部件,Patrick企图从中尽可能多地偷些东西出来.这意味着要找一条进去的路,弄晕安保人 员,穿过各种各样的激光射线,你懂的,都是

BZOJ 1059 &amp; 二分图匹配

题意: 判断一个黑白染色的棋盘能否通过交换行或列使对角线上都是黑色. SOL: 真是有点醉...这种问题要么很神要么很水...第一眼感觉很水但就是不造怎么做...想了10分钟怎么感觉就是判断个数够不够n呢然后就蹦出了一个反例...然后就忍不了百度= =... 二分图匹配真是瞎了眼...然后发现好神又好水... 显然的同一行无论怎么交换都是同一行---->根本就没往这上面想...同一列永远都是同一列,那么只要判断有多少不同行又不同列的就好了...枚举有点虚,那么就匹配吧!按照行列建图,恩就是这样.

BZOJ 4808 二分图最大独立集

思路: 棋盘是个二分图 那就把一个可以走的白点  向所有可以走的黑点连边 跑一个最大匹配   (匹配上了就代表这两个点不能共存) 最大独立集=sum-最大匹配 //By SiriusRen #include <queue> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N=222,M=N*N*21; int n,m,a[N][N

BZOJ 1433 二分图上的博弈

首先对网格染色,发现是而二分图. 那么即在二分图上选一个起点走过的点无法再走,最后无路可走就输了. 如果起点必在最大匹配中,先手必赢. 如果起点不一定在最大匹配中(包括不可能在),后手必赢.网上有解释. 因为写二分图不怎么熟练,所以还是用网络流吧. 找的就是可行的和不在最大匹配中点.建边要用单向边. 从源点和汇点开始Dfs.假如从左边开始那么先扫到右边后又扫到左边.那么那个点就是可行点. 1 #include <iostream> 2 #include <cstring> 3 #i

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

4025: 二分图 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2191  Solved: 800[Submit][Status][Discuss] Description 神犇有一个n个节点的图.因为神犇是神犇,所以在T时间内一些边会出现后消失.神犇要求出每一时间段内这个图是否是二分图.这么简单的问题神犇当然会做了,于是他想考考你. Input 输入数据的第一行是三个整数n,m,T. 第2行到第m+1行,每行4个整数u,v,start,end

LCT 填坑系列

清华冬令营 T1用了LCT 这个东西以前有写过 然而并不熟练 发现没了板子根本就不会写 只能填一填坑辣 BZOJ 2843 LCT 1 #include <bits/stdc++.h> 2 #define N 30010 3 #define ls c[x][0] 4 #define rs c[x][1] 5 using namespace std; 6 7 inline int read() 8 { 9 int x=0,f=1; char ch=getchar(); 10 while(ch&l

记录 [补档]

数学 概率论 计数问题 数论 线性代数 博弈论 比赛经验 不要通过数据大小猜测正解的时间复杂度. 把一个方法想到底. DP题假如实在不会的话, 果断跳过, 找思维量更小的数据结构题. 一些方法 二分 DP, 尤其多想矩阵乘法优化DP 网络流 FFT 日程表 Fri, Nov 10 明天就是NOIp了. 从上次记录到现在已经将近一个月了, 这个月, 真心没有进步多少, 完全不再状态. 希望不要AFO吧. 这可能是最后一篇记录了. Sun, Oct 22 AHOI 2009 中国象棋: 统计在棋盘上