分析:带权并查集,就是维护一堆关系
然后就是带权并查集的三步
1:首先确定权值数组,sum[i]代表父节点到子节点之间的1的个数(当然路径压缩后代表到根节点的个数)
1代表是奇数个,0代表偶数个
2:设计路径压缩算法 sum[x]=(sum[x]+sum[t])%2;
3:弄清合并根节点时的操作,小的在上;
注:这个题需要离散化
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N=5e3+;
struct Node{
int l,r,v;
}p[N];
int a[N<<],cnt;
char s[];
int fa[N<<],sum[N<<];
int find(int x){
if(x==fa[x])return x;
int t=fa[x];
fa[x]=find(fa[x]);
sum[x]=(sum[x]+sum[t])%;
return fa[x];
}
int main()
{
int n;
while(~scanf("%d%d",&n,&n)){
cnt=;
for(int i=;i<=n;++i){
scanf("%d%d%s",&p[i].l,&p[i].r,s);
if(s[]=='e')p[i].v=;
else p[i].v=;
--p[i].l;
a[++cnt]=p[i].l,a[++cnt]=p[i].r;
}
sort(a+,a++cnt);
cnt=unique(a+,a++cnt)-a-;
for(int i=;i<=cnt;++i)fa[i]=i,sum[i]=;
int ans=;
for(int i=;i<=n;++i){
p[i].l=lower_bound(a+,a++cnt,p[i].l)-a;
p[i].r=lower_bound(a+,a++cnt,p[i].r)-a;
int u=find(p[i].l),v=find(p[i].r);
if(u==v){
if((-sum[p[i].r]-sum[p[i].l])%!=p[i].v)break;
}
else if(u<v){
fa[v]=u;
sum[v]=sum[p[i].r]-sum[p[i].l]-p[i].v;
}
else{
fa[u]=v;
sum[u]=sum[p[i].l]-sum[p[i].r]+p[i].v;
}
++ans;
}
printf("%d\n",ans);
}
return ;
}