zoukankan      html  css  js  c++  java
  • hdu 3635 Dragon Balls 并查集

    题目大意:初始时,有n个龙珠,编号从1到n,分别对应的放在编号从1到n的城市中。现在有两种操作:

    T A B,表示把A球所在城市全部的龙珠全部转移到B城市。(第一次时,因为A球所在的城市只有一个球,所以只移动1个,如果有多个,则全部移动)。

    Q A,表示查询A。要求得到的信息分别是:A现在所在的城市,A所在城市的龙珠数目,A转移到该城市移动的次数(如果没有移动就输出0)

    这道题主要的问题是转移次数,初始时每个龙珠的转移次数为0,若将a移到b,则将a所在集合的根结点加一,表示整个a集合都移动了一次,如果查找某个节点x的移动次数,则在路径压缩时需要加上它父节点的移动次数,递归解决。

    #include <stdio.h>
    #include <string.h>
    #define maxn 10200
    int p[maxn],tran[maxn],cap[maxn];
    int t;
    
    int find(int x)
    {
    	int a;
    	if(p[x]==x) return x;
    	else 
    	{
    		a=find(p[x]);
    		tran[x]+=tran[p[x]];
    		p[x]=a;
    		return p[x];
    	}
    }
    
    void link(int a,int b)
    {
    	int x,y;
    	x=find(a);
    	y=find(b);
    	if(x!=y)
    	{
    		p[x]=y;
    		tran[x]++;
    		cap[y]+=cap[x];
    		cap[x]=0;
    	}
    }
    
    int main()
    {
    	int i,x,y;
    	int sum=0;
    	int n,q;
    	char a;
    	scanf("%d",&t);
    	while(t--)
    	{
    		scanf("%d%d",&n,&q);
    		for(i=1;i<=n;i++) { p[i]=i;cap[i]=1;tran[i]=0; }
    		sum++;
    		printf("Case %d:
    ",sum);
    		for(i=1;i<=q;i++)
    		{
    			getchar();
    			scanf("%c",&a);
    			if(a=='T')
    			{
    				scanf("%d%d",&x,&y);
    				link(x,y);
    			}
    			else
    			{
    				scanf("%d",&x);
    				int ans=find(x);
    				printf("%d %d %d
    ",ans,cap[p[x]],tran[x]);
    			}
    		}
    	}
    	return 0;
    }
    


     

  • 相关阅读:
    管道流
    构造方法中用泛型
    代码实现长提闪烁
    关联事件,向窗体中添加控件,设置控件属性等系列操作
    picturebox中添加图片
    typeof gettype
    groupbox
    static用法
    运算符重载
    类修饰符
  • 原文地址:https://www.cnblogs.com/vermouth/p/3710188.html
Copyright © 2011-2022 走看看