Topic links: Click here
Meaning of the questions:
Entry represents a length the string, denotes Then there line input, the next row input represents to the first the middle of characters number is an even number; represents to the first the middle of characters is odd number. If the first sentence is a front for the first time with the words of contradiction, the output 。
Analysis of ideas:
represents is even in this condition, represents is an odd condition that
is the same
- in case is odd, is an odd number
- in case is even, is an even number
is heterogeneous
- in case is even, is an odd number
- in case is odd, is an even number
understanding:
Sideband rights disjoint-set: and are related, they are in the same collection, as to what the relationship is depends on how much weight
Extension field of disjoint-set: the collection as long as a condition is true, then all remaining conditions established inevitable.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
const int N = 40010, base = N / 2;
int n, m;
int p[N];
map<int,int> mp;
int get(int x) // 在线离散化
{
if(mp.count(x) == 0) mp[x] = ++n;
return mp[x];
}
int find(int x)
{
if(x != p[x]) p[x] = find(p[x]);
return p[x];
}
int main()
{
scanf("%d%d", &n, &m);
n = 0; // 用于离散化
for(int i = 1; i < N; ++i) p[i] = i; // 初始化
int res = m;
for(int i = 1; i <= m; ++i)
{
int a, b;
char op[6];
scanf("%d%d%s", &a, &b, op);
if(res != m) continue;
a = get(a - 1), b = get(b);
if(op[0] == 'e') // 同类
{
if(find(a + base) == find(b)) // 有矛盾
{
res = i - 1;
break; // 数据没有输入完,可以break
}
p[find(a)] = find(b);
p[find(a + base)] = find(b + base);
}
else // 异类
{
if(find(a) == find(b)) // 有矛盾
{
res = i - 1;
break;
}
p[find(a)] = find(b + base);
p[find(a + base)] = find(b);
}
}
printf("%d\n", res);
return 0;
}