BZOJ4025 二分图

(这里的并查集不用路径压缩，只要按秩合并，这样子可以保证单次操作的时间复杂度是$O(logn)$的)

  1 /**************************************************************
2     Problem: 4025
3     User: rausen
4     Language: C++
5     Result: Accepted
6     Time:4344 ms
7     Memory:6668 kb
8 ****************************************************************/
9
10 #include <cstdio>
11 #include <algorithm>
12
13 using namespace std;
14 const int N = 1e5 + 5;
15 const int M = 2e5 + 5;
16
17 inline int read();
18
19 struct edge {
20     int x, y, st, ed;
21
22     inline void get() {
23         x = read(), y = read();
24         st = read() + 1, ed = read();
25     }
26 } e[M];
27
28 int n, m, time;
29
30 namespace set {
31     int fa[N], d[N], a[N];
32     int s[N << 2], top = 0;
33
34     int find(int x) {
35         while (fa[x] != x) x = fa[x];
36         return x;
37     }
38     int dep(int x) {
39         static int res;
40         for (res = 0; fa[x] != x; x = fa[x])
41             res ^= a[x];
42         return res;
43     }
44
45     void set_union(int x, int y, int _d) {
46         if (d[x] > d[y]) swap(x, y);
47         if (d[x] == d[y]) ++d[y], s[++top] = -y;
48         fa[x] = y, a[x] = _d, s[++top] = x;
49     }
50
51     void set_resume(int t) {
52         for (; top != t; --top)
53             if (s[top] < 0) --d[-s[top]];
54             else fa[s[top]] = s[top], a[s[top]] = 0;
55     }
56 }
57 using namespace set;
58
59 void work(int l, int r, int m) {
60     int mid = l + r >> 1, now = top;
61     int i, j, fx, fy, _d;
62     for (i = 1; i <= m; ++i)
63         if (e[i].st <= l && r <= e[i].ed) {
64             fx = find(e[i].x), fy = find(e[i].y), _d = !(dep(e[i].x) ^ dep(e[i].y));
65             if (fx != fy) set_union(fx, fy, _d);
66             else if (_d) {
67                 while (l <= r)
68                     puts("No"), ++l;
69                 set_resume(now);
70                 return;
71             }
72             swap(e[m--], e[i--]);
73         };
74     if (l == r) puts("Yes");
75     else {
76         for (i = 1, j = m; i <= j; ++i)
77             if (e[i].st > mid) swap(e[j--], e[i--]);
78         work(l, mid, j);
79         for (i = 1, j = m; i <= j; ++i)
80             if (e[i].ed <= mid) swap(e[j--], e[i--]);
81         work(mid + 1, r, j);
82     }
83     set_resume(now);
84 }
85
86 int main() {
87     int i;
88     n = read(), m = read(), time = read();
89     for (i = 1; i <= n; ++i)
90         fa[i] = i, d[i] = 1, a[i] = 0;
91     for (i = 1; i <= m; ++i) e[i].get();
92     for (i = 1; i <= m; ++i)
93         if (e[i].st > e[i].ed) swap(e[i--], e[m--]);
94     work(1, time, m);
95     return 0;
96 }
97
98 inline int read() {
99     static int x, sgn;
100     static char ch;
101     x = 0, sgn = 1, ch = getchar();
102     while (ch < '0' || '9' < ch) {
103         if (ch == '-') sgn = -1;
104         ch = getchar();
105     }
106     while ('0' <= ch && ch <= '9') {
107         x = x * 10 + ch - '0';
108         ch = getchar();
109     }
110     return sgn * x;
111 }
View Code

By Xs酱~ 转载请说明 博客地址：http://www.cnblogs.com/rausen
posted on 2015-05-13 23:08  Xs酱~  阅读(1125)  评论(1编辑  收藏  举报