POJ_1733_(并查集+离散化)
- 带权并查集
- 权值既可以通过异或来表示奇偶的数量,也可以直接存奇偶数量
1
2
,路径压缩的时候累加起来就行了 - 此题点的范围太大,需要离散化,注意输入的次数最多为
5000
,则最多有1e4
个点, - 带权并查集+离散化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65#include <iostream>
#include <string.h>
#include <string>
#include <map>
using namespace std;
const int maxn = 1e4 + 5;
int n,m;
int pre[maxn];
int rala[maxn];
map<int,int> e;
void init() {
memset(rala,0,sizeof rala);
for (int i=1; i<=maxn; i++) pre[i] = i;
}
int find(int x) {
int temp = pre[x];
if (x == pre[x]) return x;
pre[x] = find(pre[x]);
rala[x] ^= rala[temp];
return pre[x];
}
bool merge(int a,int b,int k) {
int ra = find(a);
int rb = find(b);
if (ra == rb) {
if ( (rala[a] ^ rala[b]) != k )
return 0;
else return 1;
}
pre[ra] = rb;
rala[ra] = rala[a] ^ rala[b] ^ k;
return 1;
}
int a,b;
string s;
int cnt;
int main() {
// freopen("a.txt","r",stdin);
cin >> n >> m;
if (m==0) cout << m << endl;
init();
for (int i=1; i<=m; i++) {
cin >> a >> b >> s;
bool k;
b++;
if (s == "even") k = 0;
else k = 1;
map<int,int>::iterator it1,it2;
it1 = e.find(a);
if (it1 == e.end()) e[a]=cnt++;
it2 = e.find(b);
if (it2 == e.end()) e[b]=cnt++;
if (!merge(e[a],e[b],k)) {
cout << i-1 << endl;
break;
}
else if (i == m ) cout << i << endl;
}
return 0;
}
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!