思路:d(i, j)表示区间(i, j]的1的个数的奇偶性。输入最多共有5000*2个点,需要离散化处理一下。剩下的就是并查集判冲突。
AC代码
#include <cstdio>
#include <cmath>
#include <cctype>
#include <algorithm>
#include <cstring>
#include <utility>
#include <string>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define eps 1e-10
#define inf 0x3f3f3f3f
#define PI pair<int, int>
typedef long long LL;
const int maxn = 1e4 + 5;
int n, m;
struct node{
int par;
int real;
}a[maxn];
struct Edge{
int u, v, k;
}b[maxn];
void init(int num) {
for(int i = 0; i < num; ++i) {
a[i].par = i;
a[i].real = 0;
}
}
int find(int x) {
if(a[x].par == x) return x;
int r = find(a[x].par);
a[x].real = a[x].real ^ a[a[x].par].real;
return a[x].par = r;
}
bool unionset(int x, int y, int real) {
int rx = find(x), ry = find(y);
if(rx == ry) {
if(real != (a[x].real ^ a[y].real)) return false;
}
else {
a[rx].par = y;
a[rx].real = a[x].real ^ real;
}
return true;
}
void deal() { //离散化处理
map<int, int>ha;
vector<int>v;
for(int i = 0; i < m; ++i) {
if(!ha.count(b[i].u)) {
ha[b[i].u] = 1;
v.push_back(b[i].u);
}
if(!ha.count(b[i].v)) {
ha[b[i].v] = 1;
v.push_back(b[i].v);
}
}
sort(v.begin(), v.end());
int id = 0;
for(int i = 0; i < v.size(); ++i) {
ha[v[i]] = id++;
}
init(id);
for(int i = 0; i < m; ++i) {
b[i].u = ha[b[i].u];
b[i].v = ha[b[i].v];
}
}
int main() {
while(scanf("%d%d", &n, &m) == 2) {
char s[10];
for(int i = 0; i < m; ++i) {
scanf("%d%d%s", &b[i].u, &b[i].v, s);
b[i].u--;
if(s[0] == 'o') b[i].k = 1; //奇数
else b[i].k = 0;
}
deal();
int ans = 0, flag = 1;
for(int i = 0; i < m; ++i) {
ans = i;
if(!unionset(b[i].u, b[i].v, b[i].k)) {
flag = 0;
break;
}
}
if(flag) ans = m;
printf("%d\n", ans);
}
return 0;
}
如有不当之处欢迎指出!