• spoj Corporative Network


    题目描述

    原本有 n 个节点,最初每个节点的父亲都是自己。

    现在给你若干操作,共分为两种,操作格式如下:

    I x y(大写字母I)
    将 x 的父亲变为 y,而且令 x 与 y 之间的距离为 (lvert x-y vert mod 1000)

    E x 询问x点到其根节点的距离
    数据保证对于所有的 1 操作合法,即保证之前 y 不是 x 的父亲、

    输入格式

    第一行输入一个整数 T,表示每个数据点的数据组数。

    接下来对于每组数据输入格式如下:

    第一行包含一个正整数 n,表示原有的节点个数

    从第二行开始,以下有若干行,每一行的输入格式为

    I x y 或E x 分别代表以上的两种操作

    对于这些操作,以输入一个O(大写字母O)为终止。

    输出格式

    一共若干行,表示对于每一组测试数据中的 E 操作输出答案。

    输入输出样例

    输入

    1
    4
    E 3
    I 3 1
    E 3
    I 1 2
    E 3
    I 2 4
    E 3
    O
    

    输出

    0
    2
    3
    5
    

    带权并查集


    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=2e4+10;
    int f[maxn],dis[maxn];
    int t,n;
    char s[3];
    void join(int x,int y)
    {
    	f[x]=y;
    	dis[x]+=x>y?((x-y)%1000):((y-x)%1000);
    }
    int find(int x)
    {
    	if(f[x]==x)return x;
    	int fa=f[x];
    	f[x]=find(f[x]);
    	dis[x]=dis[x]+dis[fa];	
    	return f[x];
    }
    int main()
    {
    	scanf("%d",&t);
    	while(t--)
    	{
    		scanf("%d",&n);
    		for(int i=0;i<=n;++i)f[i]=i,dis[i]=0;
    		int x,y;
    		do
    		{
    			scanf("%s",s);
    			if(s[0]=='O')break;
    			if(s[0]=='I')
    			{
    				scanf("%d%d",&x,&y);
    				join(x,y);
    			}
    			else
    			{
    				scanf("%d",&x);
    				find(x);
    				printf("%d
    ",dis[x]);
    			}
    		}while(1);
    	}
    	return 0;
    }
    
  • 相关阅读:
    CLRS 10.28
    [转]教你如何查看各种浏览器的Cookies[IE cookies信息]
    红黑树c实现
    ubuntu下eclipse中键盘失灵
    putty中文乱码解决
    [ 转]关于linux下wireshark启动时Lua报错
    c/c++运算符优先级
    CLRS 10.45
    ubuntu 12.04 安装NS2
    SQL IsDate()
  • 原文地址:https://www.cnblogs.com/gryzy/p/15164803.html
Copyright © 2020-2023  润新知