zoukankan      html  css  js  c++  java
  • 洛谷 P1196 银河英雄传说

    P1196 银河英雄传说

    加权并查集,简介见加权并查集,具体方法见代码及注释

    //P1196 银河英雄传说
    #include<cstdio>
    int fa[30010];
    int r[30010];//r[i]表示第i号战舰在其父亲之后的第r[i]个位置
    int r2[30010];//r2[i]表示以第i号战舰为队首的队列有r2[i]辆战舰
    //本来只想到了记录战舰i后面的战舰数量,但是操作量太大,这里是受到其他人启发了 
    int t;
    int getans(int x,int y)//计算x与y之间战舰数量,"之间"指的就是不包括x和y本身
    {
    	if(x==y)
    		return 0;
    	if(x>y)
    		return x-y-1;
    	if(x<y)
    		return y-x-1;
    }
    int find(int x)
    {
    	if(fa[x]==x)	return x;
    	int t=find(fa[x]);
    	r[x]+=r[fa[x]];//路径压缩,x在fa[x]之后的r[x]个位置,fa[x]在t之后的r[fa[x]]个位置,因此x在t之后的r[x]+r[fa[x]]个位置处
    	fa[x]=t;
    	return t;//返回根结点
    }
    void union1(int x,int y)
    {
    	int fx=find(x);
    	int fy=find(y);
    	fa[fx]=fy;//将x所在集合(fx)并入y所在集合(fy)
    	r[fx]=r2[fy];//fx集合所有战舰前方战舰数量都增加,但是暂时只更新根结点
    	r2[fy]+=r2[fx];//以fy为首的队列战舰数量增加fx集合的战舰数量
    	//r2[fx]=0;//fx集合战舰数量归零(没有这一步也没有关系,因为没有队列分离操作,这个值不再起作用)
    }
    int main()
    {
    	int i,x,y,fx,fy;
    	char c;
    	scanf("%d",&t);
    	for(i=1;i<=30000;i++)
    	{
    		fa[i]=i;
    		r2[i]=1;
    	}
    	for(i=1;i<=t;i++)
    	{
    		scanf("
    %c%d%d",&c,&x,&y);
    		if(c=='M')
    			union1(x,y);
    		else
    		{
    			fx=find(x);
    			fy=find(y);
    			if(fx!=fy)
    				printf("-1
    ");
    			else
    				printf("%d
    ",getans(r[x],r[y]));
    		}
    	}
    	return 0;
    }


  • 相关阅读:
    [整理]Win下好用的Markdown工具
    tcpip http socket
    [整理].net中的延迟初始化器
    [整理]ASP.NET WEB API 2学习
    [整理]ASP.NET MVC 5
    [转载]AngularJS 指令 用法
    [整理]HTML5 WebSocket
    [整理]CSS3 滤镜
    [整理]WebAPP开发的框架
    [整理]AngularJS移动端开发遇到的问题
  • 原文地址:https://www.cnblogs.com/hehe54321/p/8470451.html
Copyright © 2011-2022 走看看