思路: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; }
如有不当之处欢迎指出!