算法笔记

带权并查集大神详解:https://agatelee.cn/2017/05/%E5%B8%A6%E6%9D%83%E5%B9%B6%E6%9F%A5%E9%9B%86/

贴几道题的代码:

①Poj1182食物链

#include<iostream>
#include<cstdio>
using namespace std;
const int N=1e5+5;
int fa[N],rnk[N];
void Init(int n)
{for(int i=0;i<=n;i++){fa[i]=i;rnk[i]=0;}
}
int Find(int x)
{if(x==fa[x])return x;int temp=fa[x];fa[x]=Find(fa[x]);rnk[x]=(rnk[x]+rnk[temp])%3;return fa[x];
}
void Merge(int r,int x,int y)
{int rx=Find(x);int ry=Find(y);if(rx==ry)return  ;fa[rx]=ry;rnk[rx]=(r+rnk[y]-rnk[x]+3)%3;
}
int main()
{int n,k;cin>>n>>k;Init(n);int ans=0;while(k--){int a,b,c;scanf("%d%d%d",&a,&b,&c);a--;if(b>n||c>n){ans++;continue;}if(a==1&&b==c){ans++;continue;}int rb=Find(b);int rc=Find(c);if(rb!=rc)Merge(a,b,c);else{if((rnk[b]-rnk[c]+3)%3!=a)ans++;}}cout<<ans<<endl;return 0;
}

这道题目不知道为啥用ios::sync_with_stdio(false)和cin是TLE,用ios:cync_with_stdi(false)和scanf()是WA。

详见知乎:用ios::sync_with_stdio(false)有什么坏处

②Hiho 1515分数调查

#include<iostream>
#include<cstdio>
using namespace std;
const int N=1e5+5;
int fa[N],rnk[N];
void Init(int n)
{for(int i=0;i<=n;i++){fa[i]=i;rnk[i]=0;}
}
int Find(int x)
{if(x==fa[x])return x;int temp=fa[x];fa[x]=Find(fa[x]);rnk[x]=rnk[x]+rnk[temp];return fa[x];
}
void Merge(int s,int x,int y)
{int rx=Find(x);int ry=Find(y);if(rx==ry)return  ;fa[rx]=ry;rnk[rx]=s+rnk[y]-rnk[x];
}
int main()
{int n,m,q;cin>>n>>m>>q;Init(n);while(m--){int a,b,c;scanf("%d%d%d",&a,&b,&c);Merge(c,a,b);}while(q--){int a,b;scanf("%d%d",&a,&b);int ra=Find(a);int rb=Find(b);if(ra!=rb)printf("-1\n");else printf("%d\n",rnk[a]-rnk[b]);}return 0;
}

③Codeforces 766D - Mahmoud and a Dictionary

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int fa[N],rnk[N];
map<string,int>ma;
void Init(int n)
{for(int i=0;i<=n;i++){fa[i]=i;rnk[i]=0;}
}
int Find(int x)
{if(x==fa[x])return x;int temp=fa[x];fa[x]=Find(fa[x]);rnk[x]=(rnk[x]+rnk[temp])%2;return fa[x];
}
void Merge(int r,int x,int y)
{int rx=Find(x);int ry=Find(y);if(rx==ry)return;fa[rx]=ry;rnk[rx]=(r+rnk[y]-rnk[x]+2)%2;
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);int n,m,q;cin>>n>>m>>q;Init(n);int a;string s1,s2;for(int i=0;i<n;i++){cin>>s1;ma[s1]=i;}while(m--){cin>>a>>s1>>s2;a--;int rs1=Find(ma[s1]);int rs2=Find(ma[s2]);if(rs1!=rs2){Merge(a,ma[s1],ma[s2]);cout<<"YES"<<endl;}else{if((rnk[ma[s1]]-rnk[ma[s2]]+2)%2!=a)cout<<"NO"<<endl;else cout<<"YES"<<endl;}}while(q--){cin>>s1>>s2;int rs1=Find(ma[s1]);int rs2=Find(ma[s2]);if(rs1!=rs2)cout<<3<<endl;else cout<<((rnk[ma[s1]]-rnk[ma[s2]]+2)%2+1)<<endl;}return 0;
}

ps:

可以用向量的方法考虑rnk之间的变化;

rnk[i] 表示的是i与i直接父亲节点的关系,在没有路径压缩之前不是i与根节点的关系,在路径压缩之后直接父亲就是根节点,此时才是与根节点的关系。所以只需要在直接父亲改变的情况下才需要改变rnk[i]的值。这点也是我最近才考虑清楚的,以前太菜了,没想清楚就以为自己懂了。

转载于:https://www.cnblogs.com/widsom/p/7121629.html

算法笔记--带权并查集及其模板题。相关推荐

  1. 学习笔记——拓展域并查集和带权并查集

    1,拓展域并查集 一般的并查集只能查找出各元素之间是否存在某一种相同的联系,如:a和b是亲戚关系,b和c是亲戚关系,这时就可以查找出a和c也存在亲戚关系.但如果存在多种相对的联系时一般的并查集就不行了 ...

  2. 【无码专区9】序列统计(带权并查集 + 前缀和建边 + dp)

    因为只有std,没有自我实现,所以是无码专区 主要是为了训练思维能力 solution才是dls正解,但是因为只有潦草几句,所以大部分会有我自己基于正解上面的算法实现过程,可能选择的算法跟std中dl ...

  3. 银河英雄传说 ← 带权并查集

    [问题描述] 有一个划分为N列的星际战场,各列依次编号为1,2,-,N. 有N艘战舰,也依次编号为1,2,-,N,其中第i号战舰处于第i列. 有T条指令,每条指令格式为以下两种之一: 1.M i j, ...

  4. 2017乌鲁木齐区域赛I(带权并查集)

    #include<bits/stdc++.h> using namespace std; int f[200010];//代表元 long long rl[200010];//记rl[i] ...

  5. BZOJ 2303 方格染色(带权并查集)

    要使得每个2*2的矩形有奇数个红色,如果我们把红色记为1,蓝色记为0,那么我们得到了这2*2的矩形里的数字异或和为1. 对于每个方格则有a(i,j)^a(i-1,j)^a(i,j-1)^a(i-1,j ...

  6. POJ1703带权并查集(距离或者异或)

    题意:       有两个黑社会帮派,有n个人,他们肯定属于两个帮派中的一个,然后有两种操作 1 D a b 给出a b 两个人不属于同一个帮派 2 A a b 问a b 两个人关系 输出 同一个帮派 ...

  7. POJ1988(带权并查集,搬砖块)

    题意:        可以这样理解,有n快方形积木,一开始都是单独的放到哪,然后有两种操作 1 M a b 把a所在的那一堆落到b所在那一堆的上面(一开始自己是一堆) 2 C a 问a下面有多少个积木 ...

  8. LA3027简单带权并查集

    题意:       有n个点,一开始大家都是独立的点,然后给出一些关系,a,b表示a是b的父亲节点,距离是abs(a-b)%1000,然后有一些询问,每次询问一个节点a到父亲节点的距离是多少? 思路: ...

  9. hdu3234 带权并查集(XOR)

    题意:       给你n个未知的正整数,有三总操作       I P V            P的值是V       I P Q V          P XOR Q = V       Q K ...

  10. hdu4829 带权并查集(题目不错)

    题意: Information Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...

最新文章

  1. IOS中类和对象还有,nil/Nil/NULL的区别
  2. SDUT OJ 数据结构实验之排序一:一趟快排
  3. ffmpeg流文件合并concat
  4. GRE写作-学生选择有助于就业的课程or根据兴趣选课?
  5. jsp页面发生异常跳转到友好页面
  6. 云服务器mqtt协议,云服务器mqtt协议
  7. svn切换分支 如何判断 是否完成_SVN创建分支/合并分支/切换分支
  8. vue弹出alert_vue+webpack 实现简单的弹窗(alert)组件
  9. 谷歌翻译 google translation api
  10. Linux超简单文本编辑器:nano
  11. 批量合并同一文件夹下工作簿-1
  12. C++ TCP socket 非阻塞连接超时设定方式
  13. 加拿大java技术移民_加拿大技术移民分析贴之新手入门级!
  14. linux达梦服务重启,如何重启达梦数据库服务
  15. Java面试题!mysql安装教程图解
  16. requests+正则表达式爬取猫眼电影TOP100!
  17. Kubernetes存储Longhorn
  18. 图解传说中的HTTP协议
  19. 解决 Virtualbox 6.1.34 出现 End kernel panic - not syncing: attempted to kill the idle task
  20. 输出图案(四)----输出正多边形图案:(难度系数:半颗星)

热门文章

  1. “我是技术总监,你为毛总问我技术细节?”
  2. FFmpeg总结(二)AV系列结构体之AVFrame
  3. python调用matlab函数_python调用matlab的m自定义函数方法
  4. python越学越不懂_为什么那么多自学Python的后来都放弃了,总结以下原因
  5. python语言中strike_基于Python的XSS测试工具XSStrike使用方法
  6. 计算机二级c语言编译题评分,计算机二级C语言题型和评分标准
  7. golang语言的类型
  8. 学生选课系统代码-3mode【DB】视图层代码【MVC--M】代码
  9. win7发现不了无线网络_Win7笔记本怎么设置wifi热点 Win7笔记本设置wifi热点方法【详解】...
  10. oracle 2的次方,Oracle第二次课 - osc_qyg23ccq的个人空间 - OSCHINA - 中文开源技术交流社区...