zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    iptables的state模块的4种封包链接状态
    添加网络设备eth0
    DOM对象与jquery对象有什么不同
    A Death in the Family May Cause Real Heart Break
    A Soft Body, but the Mind of a Robot
    Oeasy系列教程
    浏览器中的javascript
    递归算法详细分析
    Axure 运行开发工具
    Hello Mono 转载的Mono Project Tutorial
  • 原文地址:https://www.cnblogs.com/gryzy/p/15164803.html
Copyright © 2011-2022 走看看