码迷,mamicode.com
首页 > Web开发 > 详细

【并查集】UVALive3027 Corporative Network

时间:2015-08-26 12:18:11      阅读:149      评论:0      收藏:0      [点我收藏+]

标签:并查集   路径压缩   

【并查集】UVALive3027 Corporative Network

并查集——维护到根节点距离的d数组

题目大意

对n个节点操作,加边 or 询问某节点到根节点的距离

技术分享
技术分享


说一下思路

之前做过一道求连通分支最大元素个数的题目,维护的是一个cnt[ ]数组(在加边的过程中);比较这道题,可以考虑维护到根节点的距离d[ ]数组。

思路:记下每个节点到父亲节点的距离为d[i],然后在路径压缩时维护这个d数组;

在加边时只有这两个节点中的父亲节点的d需要维护,并不需要查操作,这一点的区别是相当大的!而怎样得到某节点u到根节点的距离呢?查操作。查操作本身带路径压缩的,所以不可能直接得到最终答案,必须一边路径压缩,一边维护数组d,最后输出d[u]即可

★维护过程与路径压缩同时进行,想想还是有点小麻烦!

技术分享


参考代码

#include<bits/stdc++.h>
using namespace std;

const int _max = 2e4 + 10;
char cmd[2];
int n,a,b,pre[_max],d[_max];

void init(){
  for(int i = 1; i <= n; ++ i){
    pre[i] = i;//每个元素所在集合为其自身
    d[i] = 0;//每个节点到父亲节点的距离为0
  }
}

int find(int x){//返回元素x的根节点,路径压缩过程中维护d[]数组
  if( x == pre[x]) return x;
  int root = find(pre[x]);
  d[x] += d[pre[x]];
  return  pre[x] = root;
}

void join(int a,int b){//并,按要求合并边(a,b)
  pre[a] = b;
  d[a] = (abs(a - b))%1000;
}

int main(){
 #ifndef ONLINE_JUDGE
 freopen("input.txt","r",stdin);
 #endif // ONLINE_JUDGE
 int T;cin>>T;
 while(T--){
    scanf("%d",&n);
    init();
    while(scanf("%s",cmd) == 1 && cmd[0] != ‘O‘){
        if(cmd[0] == ‘I‘){
            scanf("%d%d",&a,&b);
            join(a,b);
        }
        else{
          scanf("%d",&a);
          find(a);
          printf("%d\n",d[a]);
        }
    }
 }
 return 0;
}
  • 加粗 Ctrl + B
  • 斜体 Ctrl + I
  • 引用 Ctrl + Q
  • 插入链接 Ctrl + L
  • 插入代码 Ctrl + K
  • 插入图片 Ctrl + G
  • 提升标题 Ctrl + H
  • 有序列表 Ctrl + O
  • 无序列表 Ctrl + U
  • 横线 Ctrl + R
  • 撤销 Ctrl + Z
  • 重做 Ctrl + Y

版权声明:本文为博主原创文章,未经博主允许不得转载。

【并查集】UVALive3027 Corporative Network

标签:并查集   路径压缩   

原文地址:http://blog.csdn.net/u012717411/article/details/47999537

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!