Ural 1003(带权并查集,离散化)

2015-01-31 00:59:37

思路:一道经典的带权并查集。

  可能比较难想到用带全并查集做... 但是如果我们定义sum[i]为前i个点中1的个数,那么每个区间[a,b]中1的个数的奇偶性就可用sum[b] - sum[a - 1]的奇偶性表示。

  又由于只用考虑奇偶性,因此我们不妨让sum[i]仅记录1的个数的奇偶性,考虑把每个sum[i]看做点,这样点与点之间就满足一种向量加减关系,用带权并查集处理。

  重点:每个节点的rank值表示自己与当前根的关系,0表示奇偶性相同,1表示奇偶性不同。

  注意点:(1)Find函数中,为了防止因路径压缩而造成的fa[x]改变,要先存下fa[x]的值

      (2)main函数中合并完,还要处理Rank值的变化。如fa[y] = x之后,y不再是根,而成为x的子节点,所以其Rank[y]要相应改变。

      (3)由于数据范围大,要先进行离散化~

      (4)Rank值的变化当然可以用更加方便的“^”异或来搞定....

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <vector>
 6 #include <map>
 7 #include <set>
 8 #include <stack>
 9 #include <queue>
10 #include <string>
11 #include <iostream>
12 #include <algorithm>
13 using namespace std;
14 
15 #define MEM(a,b) memset(a,b,sizeof(a))
16 #define REP(i,n) for(int i=1;i<=(n);++i)
17 #define REV(i,n) for(int i=(n);i>=1;--i)
18 #define FOR(i,a,b) for(int i=(a);i<=(b);++i)
19 #define RFOR(i,a,b) for(int i=(a);i>=(b);--i)
20 #define MP(a,b) make_pair(a,b)
21 
22 typedef long long ll;
23 typedef pair<int,int> pii;
24 const int INF = (1 << 30) - 1;
25 const int MAXN = 10010;
26 
27 int L,N,ans;
28 int fa[MAXN],Rank[MAXN];
29 int sta[MAXN][3];
30 int tx[MAXN];
31 
32 int Find(int x){
33     if(fa[x] == x) return x;
34     int tmp = fa[x];
35     fa[x] = Find(fa[x]);
36     Rank[x] = (Rank[x] + Rank[tmp]) % 2;
37     return fa[x];
38 }
39 
40 void Init(){
41     FOR(i,0,10000) fa[i] = i;
42     MEM(Rank,0);
43 }
44 
45 int main(){
46     int a,b;
47     char s[10];
48     while(scanf("%d",&L) != EOF){
49         if(L == -1) break;
50         Init();
51         scanf("%d",&N);
52         int ans = N,cnt = 0;
53         REP(i,N){
54             scanf("%d%d%s",&sta[i][0],&sta[i][1],s);
55             int v = (s[0] == 'e') ? 0 : 1;
56             sta[i][2] = v;
57             tx[++cnt] = sta[i][0];
58             tx[++cnt] = sta[i][1];
59         }
60         sort(tx + 1,tx + cnt + 1);
61         int sz = unique(tx + 1,tx + cnt + 1) - tx;
62         REP(i,N){
63             sta[i][0] = lower_bound(tx + 1,tx + sz + 1,sta[i][0]) - tx;
64             sta[i][1] = lower_bound(tx + 1,tx + sz + 1,sta[i][1]) - tx;
65         }
66         REP(i,N){
67             a = sta[i][0];
68             b = sta[i][1];
69             int v = sta[i][2];
70             if(ans != N)
71                 continue;
72             a--;
73             int x = Find(a),y = Find(b);
74             if(x == y){
75                 if(Rank[a] ^ Rank[b] ^ v)
76                     ans = i - 1;
77             }
78             else{
79                 fa[y] = x;
80                 Rank[y] = (Rank[a] + Rank[b] + v) % 2;
81             }
82         }
83         printf("%d\n",ans);
84     }
85     return 0;
86 }

 

posted @ 2015-01-31 01:12  Naturain  阅读(203)  评论(0编辑  收藏  举报