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

 

posted @ 2017-01-11 12:08  YouSiki  阅读(271)  评论(0编辑  收藏  举报