題目大意
有一個01序列
每次給一個 兩個數x y 和他們之間的1的個數是奇數還是偶數
問 在第幾個給定的條件可以判斷這些條件存在矛盾
樣例
Sample Input
10
5
1 2 even
3 4 odd
5 6 even
1 6 even
7 10 odd
Sample Output
3
解法一: 帶邊權
思路
利用前綴和思想。 a代表a的前綴和, 由於是01序列, 所以a就代表a的前面有多少個1, a 和 b 之間的1個數是偶數, 代表a - 1 與 b 的奇偶性相同
代碼
#include <iostream>
#include <cstring>
#include <map>
#include <algorithm>
using namespace std;
const int N = 20010;
int f[N], d[N];
int n, m, cnt;
map<int, int> num;
int get(int a)
{
if(num.count(a)) return num[a];
return num[a] = ++cnt;
}
void init()
{
for(int i = 0; i <= 20000; i++)
f[i] = i;
}
int find(int x)
{
if(f[x] == x) return x;
int father = find(f[x]); //如果他的父節點到根之間是偶數0, 他到父節點是奇數1, ^結果就是1,奇數。。。等等
d[x] ^= d[f[x]];
return f[x] = father;
}
int main()
{
int n, m;
scanf("%d%d", &n, &m);
init();
int ans = m;
bool ff =- false;
for(int i = 1; i <= m; i++)
{
string s;
int a, b;
cin >> a >> b >> s;
a--;
if(ff) continue;
a = get(a); //離散化
b = get(b);
int t = 0;
if(s == "odd")
t = 1;
int fa = find(a);
int fb = find(b);
if(fa == fb)
{
if((d[a] ^ d[b]) != t)
{
ans = i - 1;
ff = true;
}
}
else{
f[fa] = fb;
d[fa] = d[a] ^ d[b] ^ t;
}
}
cout << ans << endl;
return 0;
}
解法二:擴展域
思路
a 和 a+n 代表奇偶性不同的兩個條件, 這裏的a, b代表的是條件, 不是上一個解法中的數
所以給定a, b, 如果他們之間是偶數, 那麼a, b爲同類,a + n, b + n也是同類
如果是奇數, a, b 就是異類, a + n, b就是同類
代碼
#include <iostream>
#include <cstring>
#include <map>
#include <algorithm>
using namespace std;
const int N = 40010, base = N / 2;
int f[N], d[N];
int n, m, cnt;
map<int, int> num;
int get(int a)
{
if(num.count(a)) return num[a];
return num[a] = ++cnt;
}
void init()
{
for(int i = 0; i <= 40000; i++)
f[i] = i;
}
int find(int x)
{
if(f[x] == x) return x;
return f[x] = find(f[x]);
}
int main()
{
int n, m;
scanf("%d%d", &n, &m);
init();
int ans = m;
bool ff =- false;
for(int i = 1; i <= m; i++)
{
string s;
int a, b;
cin >> a >> b >> s;
a--;
if(ff) continue;
a = get(a); //離散化
b = get(b);
if(s == "even")
{
if(find(a) == find(b + base))
{
ans = i - 1;
ff = true;
}
f[find(a)] = find(b);
f[find(a + base)] = find(b + base);
}
else{
if(find(a) == find(b))
{
ans = i - 1;
ff = true;
}
f[find(a)] = find(b + base);
f[find(a + base)] = find(b);
}
}
cout << ans << endl;
return 0;
}