1329 - Corporative Network(并查集)
2015-09-20 09:52
148 查看
题目链接
该题是比较经典的并查集题目,经典在需要在路径压缩时维护一些量。 由于每棵树除了根结点不能换之外,其他结点的位置可以任意改变,这恰好符合并查集的特点。
但是如果用最朴素的方法维护每个结点到根的距离,那么每次新加入的结点就要向上遍历一遍所有结点,时间复杂度难以承受(因为无法路径压缩) 。 所以我们可以在路径压缩的时候顺便求出d值 。 在每次返回某个结点的祖先之前先将当前结点的d值更新,即加上当前父结点的d值, 然后就可以路径压缩了。
所以这么做的原因是为了防止并查集退化成一条长长的链表,为了不牺牲路径压缩这个好东西。
细节参见代码:
该题是比较经典的并查集题目,经典在需要在路径压缩时维护一些量。 由于每棵树除了根结点不能换之外,其他结点的位置可以任意改变,这恰好符合并查集的特点。
但是如果用最朴素的方法维护每个结点到根的距离,那么每次新加入的结点就要向上遍历一遍所有结点,时间复杂度难以承受(因为无法路径压缩) 。 所以我们可以在路径压缩的时候顺便求出d值 。 在每次返回某个结点的祖先之前先将当前结点的d值更新,即加上当前父结点的d值, 然后就可以路径压缩了。
所以这么做的原因是为了防止并查集退化成一条长长的链表,为了不牺牲路径压缩这个好东西。
细节参见代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int mod = 1000; const int maxn = 20000 + 5; const int INF = 1000000000; int T,n,m,x,y,p[maxn],d[maxn]; void init(int v) { for(int i=1;i<=v;i++) p[i] = i,d[i] = 0; } int findset(int x) { if(p[x] == x) return x; else { int root = findset(p[x]); d[x] += d[p[x]]; return p[x] = root; } } char s[5]; int main() { scanf("%d",&T); while(T--) { scanf("%d",&n); init(n); while(~scanf("%s",s)&&s[0]!='O') { if(s[0] == 'E') { scanf("%d",&x); findset(x); printf("%d\n",d[x]); } else { scanf("%d%d",&x,&y); p[x] = y ; d[x] = abs(x - y)%mod; } } } return 0; }
相关文章推荐
- Studying GIT
- hibernate简介(Session,几种状态,方法······等)
- 关于自己的苹果手机——排查APP是否中招XCODE
- 因果图
- switch case语句
- Ubuntu 输入密码之后闪现一下又回答输入密码界面
- Dozer(JavaBean的映射工具)开发手册
- storm的搭建(单机版)
- MySQL备份与恢复
- android eclipse基础开发环境搭建(最新安卓6.0 SDK)
- 【MySQL】查看MySQL配置文件路径及相关配置
- 白盒测试
- python之模块的导入和用户的交互格式化输出
- 安卓开发_自定义控件_界面的简单侧滑
- ahu - 572
- 方法内部类
- Android贴吧系统学习-----悬浮布局的做法
- Android 学习之一
- 动态网页数据的采集方案
- android 进程间通信---Service Manager(2)