食物链-NC16884 / POJ1182
带权并查集 向量
带权并查集就不用多讲了,是写这题需要的前置知识,解法思路上这里使用向量偏移。
ps:表示网上写向量作法的博客普遍有点水看不下去了,补上自己的理解和图解。
结合代码和相关变量更便于理解
路径压缩:
合并集合:
代码:
int n,m,k,q;
//dsu
int pre[maxn],val[maxn],ans=0;
int find(int x)
{
if(pre[x]==x) return x;
int far=find(pre[x]);
val[x] = (val[x]+val[pre[x]]) %3;
return pre[x]=far;
}
void join(int x,int y,int s)
{
int fx=find(x),fy=find(y);
if(fx!=fy)
{
pre[fx] = fy;
val[fx] = (-val[x]+val[y]+3+s) %3;
}
else if((val[x]-val[y]+3)%3 != s) ans++;
}
//
void solve()
{
cin>>n>>k;
for(int i=1;i<=n;i++) pre[i]=i,val[i]=0;
int d,x,y;
while(k--)
{
cin>>d>>x>>y;
if(x>n||y>n||(x==y&&d==2))
{
ans++;
continue;
}
join(x,y,d-1);
}
cout<<ans<<endl;
}