带权并查集(hdu 3635,hdu 2818)
来源:互联网 发布:淘宝网天猫女装秋装 编辑:程序博客网 时间:2024/06/05 02:27
带权并查集:
http://acm.hdu.edu.cn/showproblem.php?pid=3635
根据题意可得,我们要求某个球移动了多少次,一个城市有多少个球。
对于第二个问题很好解决,当我们用并查集并的时候,将子节点内的球全部赋给父节点,即num[parent]+=num[loof];
第一个问题才是大家纠结的。我们想一下,当将并查集的子节点连接到父节点时即表示子节点内的所有球都移动了一次,并查集最终形成的是一棵树,我们只需要求叶子节点到根节点的距离。叶子节点表示的是球开始的位置,根节点则是球现在所在的位置。这样我们就可以在并查集查原始父节点的时候来求,即每次都加上父节点到父节点的父节点的次数即可以求的。
#include <iostream>#include <cstdio>#include <cstring>#define MAX 10200using namespace std;int parent[MAX],Rank[MAX],num[MAX];int n,m,flag;void init(){for(int i=1; i<=n; i++){Rank[i]=0;num[i]=1; parent[i]=i;}flag++;}int find(int x){if(parent[x]!=x){int temp=parent[x];parent[x]=find(parent[x]);Rank[x]+=Rank[temp]; //每次加上父节点到父节点的父节点的次数} return parent[x];}void Union(int a,int b){int root_a=find(a),root_b=find(b);if(root_a==root_b) return;parent[root_a]=root_b;num[root_b]+=num[root_a]; //子节点的球的全部放到根节点上num[root_a]=0; //子节点 上的球个数为0Rank[root_a]=1; //对于每个子节点,并一次即移动一次。}void solve(){char ch[2];int a,b;printf("Case %d:\n",flag);for(int i=1; i<=m; i++){cin>>ch;if(ch[0]=='T'){cin>>a>>b;Union(a,b);}else{cin>>a;find(a);printf("%d %d %d\n",parent[a],num[parent[a]],Rank[a]);}}}int main(){int t;cin>>t;flag=0;while(t--){cin>>n>>m;init();solve();}return 0;}
hdu 2818
http://acm.hdu.edu.cn/showproblem.php?pid=2818
这题数据太坑,说了1~N的,结果包含了0,坑啊
这道题与POJ1988一样
http://poj.org/problem?id=1988
#include <iostream>#include <cstring>#include <cstdio>#define MAX 30100using namespace std;int parent[MAX],num[MAX],Rank[MAX];int n;void init(){ for(int i=0; i<MAX; i++) { parent[i]=i; num[i]=1; //表明树桩上有多少个石块 Rank[i]=0; //石块i下面有多少石块 }}int find(int x){ if(parent[x]!=x) { int temp=parent[x]; parent[x]=find(parent[x]); Rank[x]+=Rank[temp]; } return parent[x];}void Union(int a,int b){ int root_a=find(a), root_b=find(b); if(root_a==root_b) return; parent[root_a]=root_b; Rank[root_a]=num[root_b]; //让连接到根节点的节点的值等于根节点上的石块数目,这样可以在查操作的时候更新每个石块下有多少石块 num[root_b]+=num[root_a]; //将所有子节点上的石块移动到根节点
num[root_a]=0;
}void solve(){ char ch[2]; int a,b; for(int i=1; i<=n; i++) { cin>>ch; if(ch[0]=='M') { cin>>a>>b; Union(a,b); } else { cin>>a; find(a); printf("%d\n",Rank[a]); } }}int main(){ while(cin>>n) { init(); solve(); } return 0;}
- 带权并查集(hdu 3635,hdu 2818)
- hdu 2818 带权并查集
- hdu 3635 带权并查集
- HDU 3635 带权并查集
- HDU 2818 (带权并查集)
- HDU 2818 Building Block(带权并查集)
- hdu 2818(带权并查集)
- HDU 2818 Building Block(带权并查集)
- HDU 2818 Building Block(带权并查集)
- HDU 2818 Building Block (带权并查集)
- HDU 3635 Dragon Balls(带权并查集)
- hdu 3635 Dragon Balls(带权并查集)
- hdu 3047 带权并查集
- hdu 3038带权并查集
- hdu-3038 带权并查集
- HDU 3047 带权并查集
- HDU 3074 带权并查集
- HDU 3047 带权并查集
- 趋势笔试
- 一个电脑tomcat是可以同时跑 cas,imatrix项目的
- mapreduce实现"浏览该商品的人大多数还浏览了"经典应用
- 通过Spring Mail Api发送邮件
- xp引导linux
- 带权并查集(hdu 3635,hdu 2818)
- Unity3d开发android项目时引入jar包读取图片资源的问题
- ANDROID版本
- 关于适配的一些小小心得(iOS7)
- 在Java中,操作日期主要涉及到一下几个类
- 对象的序列化和反序列化
- 安装11gR2的psu后报ORA-15183错误
- IE 条件解释的语句
- 用谷歌搜索遇到“无法显示此网页”时怎么办?