核心思想:带权并查集
#include<iostream>
using namespace std;
const int N=50010;
int n,m;
int p[N],d[N];
//找到祖宗节点(路径压缩) 并求出对应距离
int find(int x){
if(p[x]!=x){
int u=p[x]; //保存旧父节点
d[x] += d[u];
p[x] = find(p[x]); //路径压缩 所有节点指向祖宗节点
}
return p[x];
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++) p[i]=i; //初始化
int res=0;
while(m--){
int t,x,y;
cin>>t>>x>>y;
if(x>n||y>n) res++; //超出范围
else{
int px=find(x),py=find(y); //找到xy的祖宗节点
if(t==1){ //说明是同类 判断对错
if(px==py && (d[x]-d[y]) % 3!=0) res++; //说明在一个并查集中,且xy不同类(距离不是3的倍数)
else if (px != py){ //不在一个并查集
p[px] = py; //将x的祖宗节点的父节点改成y的祖宗节点
d[px] = d[y] - d[x]; //xy同类->路径长度推算d[y]-d[x]
}
}
else{ //说明是异类 判断对错
if(px==py && (d[x]-d[y]-1)%3!=0) res++; //说明在一个并查集中,且x不能吃y(d[x]!=d[y]+1+3*k)
else if (px != py){
p[px] = py;
d[px] = d[y] +1 -d[x]; //x吃y->推算d[px]长度
}
}
}
}
cout<<res;
}
```
原文地址:https://blog.csdn.net/Pisasama/article/details/134658866
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_6779.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!