题目大意
有一个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;
}