并查集_记录点到根的距离

2017-03-28  本文已影响0人  Gitfan

https://scut.online/problem.php?id=78

题目描述
寓所共有n台服务器,服务器群可以看做是一些定根树组成的森林。一开始n台服务器互不相通且每台服务器均以自身为根服务器。帕秋莉会进行两种操作:
U u v w,表示将 v 结点的根服务器 root(v) 作为 u 结点的根服务器 root(u)的子结点接在 root(u) 上,并且 root(v) 到 root(u)的距离为 w。若 root(v) == root(u),则不进行任何操作(注意,此时 root(v) 的所有子结点的根结点均变为root(u),例如: root(v)会变为 root(u) );
C u,表示查询并返回u 到 root(u) 的距离。

输入格式
第一行为两个正整数n,m(1<=n<=100000,1<=m<=600000),表示服务器个数和操作次数;接下来m行,每行开头是一个字母‘U’或‘C’,表示操作种类:若开头字母为‘U’,则表示操作1。接下来会跟着三个数u,v,w(1 <= u, v <= n,1<=w<=100),表示将root(v)作为root(u)的子结点接在root(u)上,并且root(v)到root(u)的距离为w。若root(v) == root(u),则不进行任何操作;若开头字母为‘C’,则表示操作2。接下来会跟着一个数u(1<=u<=n),表示查询结点u到其跟结点的距离。
输出格式
对于每个操作2,输出一行整数,表示查询的结点到其根结点的距离。
输入
5 6
C 4
U 4 2 51
C 2
U 3 1 2
U 3 4 6
C 2
输出
0
51
57

#include<stdio.h>
#include <string.h>
using namespace std;
#define maxn 100010
int fa[maxn];
int dis[maxn];
int father(int u)
{
    if(u==fa[u]) return u;
    int root=father(fa[u]);
    dis[u]=dis[u]+dis[fa[u]];
    return fa[u]=root;
}
void connect(int u,int v,int w)
{
    int fu=father(u);
    int fv=father(v);
    if(fu==fv) return ;
    fa[fu]=fv;
    dis[fu]=w;
}
int main()
{
   int n,m,u,v,w;
   scanf("%d%d",&n,&m);
   for(int i=1;i<=n;i++)
   {
       fa[i]=i;
       dis[i]=0;
   } 
    char s;
    getchar();
   for(int i=1;i<=m;i++)
   {
       s=getchar();
       if(s=='C')
       {
           scanf("%d",&u);
            father(u);
           printf("%d\n",dis[u]);
       }
       else
        {
            scanf("%d%d%d",&u,&v,&w);
            connect(v,u,w);
        }
        getchar();
   }
}
上一篇下一篇

猜你喜欢

热点阅读