poj 1733 Parity game - 并查集

题目传送门

  传送点I

  传送点II

题目大意

  有一个很长很长的01串(你不知道是什么)。有$n$条线索,每条线索是01串上的一段的1的个数的奇偶性。求最小的$X$,使得存在一个串满足前$X$条线索,但不存在串满足前$X + 1$条线索或者输出$n$表示存在一个串满足所有线索。

  将区间求和变成前缀和相减,这样每条线索等价于告诉你两个位置的前缀和奇偶性是否相同。

  直接上带权并查集维护。对于每条线索如果涉及的两个位置没有连通就连通,否则判断是否合法。

Code

 1 /**
 2  * poj
 3  * Problem#1733
 4  * Accepted
 5  * Time: 32ms
 6  * Memory: 816k
 7  */ 
 8 #include <algorithm>
 9 #include <iostream>
10 #include <cstdlib>
11 #include <cstdio>
12 using namespace std;
13 typedef bool boolean;
14 
15 const int N = 5e3 + 5;
16 
17 int L, n;
18 char str[10];
19 pair<int, int> ps[N];
20 boolean relation[N];
21 int buf[N << 1];
22 int uf[N << 1], mask[N << 1];
23 
24 inline void init() {
25     scanf("%d%d", &L, &n);
26     for (int i = 1; i <= n; i++) {
27         scanf("%d%d%s", &ps[i].first, &ps[i].second, str);
28         ps[i].first--;
29         relation[i] = (str[0] == 'o');
30         buf[(i << 1) - 1] = ps[i].first, buf[(i << 1)] = ps[i].second;
31     }        
32 }
33 
34 void discrete() {
35     sort(buf + 1, buf + (n << 1) + 1);
36     for (int i = 1; i <= n; i++) {
37         ps[i].first = lower_bound(buf + 1, buf + (n << 1) + 1, ps[i].first) - buf;
38         ps[i].second = lower_bound(buf + 1, buf + (n << 1) + 1, ps[i].second) - buf;
39     }
40 }
41 
42 int find(int x) {
43     if (uf[x] == x)
44         return x;
45     int lastfather = uf[x];
46     uf[x] = find(uf[x]);
47     mask[x] ^= mask[lastfather];
48     return uf[x];
49 }
50 
51 inline void solve() {
52     int doublen = n << 1;
53     for (int i = 1; i <= doublen; i++)
54         uf[i] = i, mask[i] = 0;
55     for (int i = 1; i <= n; i++) {
56         if (find(ps[i].first) == find(ps[i].second)) {
57             int val1 = mask[ps[i].first], val2 = mask[ps[i].second];
58             if ((val1 ^ val2) != relation[i]) {
59                 printf("%d\n", i - 1);
60                 return;
61             }
62         } else {
63             int ffather = find(ps[i].first);
64             mask[ffather] = relation[i] ^ mask[ps[i].first];
65             uf[ffather] = ps[i].second;
66         }
67     }
68     printf("%d\n", n);
69 }
70 
71 int main() {
72     init();
73     discrete();
74     solve();
75     return 0;
76 }
posted @ 2018-08-04 23:18 阿波罗2003 阅读(...) 评论(...) 编辑 收藏