权值并查集
(x,y) | (y,z) | (x,z) |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
显然是异或关系
#include<cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <vector>
using namespace std;
#define fst first
#define sec second
#define sci(num) scanf("%d",&num)
#define scl(num) scanf("%lld",&num)
#define mem(a,b) memset(a,b,sizeof a)
#define cpy(a,b) memcopy(a,b,sizeof b)
typedef long long LL;
typedef pair<int,int> P;
const int MAX_N = 10010;
const int MAX_M = 10000;
struct Iter{
int l,r,f;
} iter[MAX_N];
int locs[MAX_N],loc = 0;
int Fa[MAX_N],R[MAX_N],N,M,Q;
void init() {
for (int i = 0;i < MAX_N;i++) {
Fa[i] = i;
R[i] = 0;
}
}
int Find(int x) {
if (Fa[x] != x) {
int p = Fa[x];
Fa[x] = Find(Fa[x]);
R[x] = R[x] ^ R[p];
}
return Fa[x];
}
int main() {
sci(M);
sci(Q);
for (int i = 0;i < Q;i++) {
char str[10];
scanf("%d%d%s",&iter[i].l,&iter[i].r,str);
iter[i].l--;
locs[loc++] = iter[i].l;
locs[loc++] = iter[i].r;
if (str[0] == 'o') {
iter[i].f = 1;
} else {
iter[i].f = 0;
}
}
init();
sort(locs,locs+loc);
loc = unique(locs,locs+loc) - locs;
for (int i = 0;i < Q;i++) {
int loc1 = lower_bound(locs,locs+loc,iter[i].l) - locs;
int loc2 = lower_bound(locs,locs+loc,iter[i].r) - locs;
int lf = Find(loc1);
int rf = Find(loc2);
if (lf == rf) { //判断是否在一个集合
if (iter[i].f != (R[loc1] ^ R[loc2])) { //此时R已经表示为与父亲节点关系,判断其对应关系是否满足iter[i]^f
printf("%d\n",i);
return 0;
}
} else {
Fa[lf] = rf;
//已经知道 (loc1,lf) (loc2,rf) 求(lf,rf)
// (loc1,lf) ^ (lf,rf) == R(loc1,loc2) ^ (loc2,rf)
if (iter[i].f == 0) { //
R[lf] = R[loc1] ^ R[loc2];
} else {
R[lf] = R[loc1] ^ R[loc2] ^ iter[i].f;
}
}
}
printf("%d\n",Q);
return 0;
}