zoukankan      html  css  js  c++  java
  • 【解题报告】 [NOI2002]银河英雄传说

    【解题报告】[NOI2002]银河英雄传说

    题目:luogu P1196


    题意简述

    处理M个指令,都为两种如下形式的指令之一

    1.M i j 表示让第i好战舰所在列的全部战舰保持原有顺序,接在第j好战舰所在列的尾部。

    2.C i j,表示询问第i号战舰与第j号战舰当前是否处于同一列中,如果在同一列中,它们之间间隔了多少艘战舰。如果不在同一列中,输出-1;

    解题思路

    并查集

    第二个指令我们要知道i,j两号战舰差多少,维护一个数列d即可,d[x]代表x前面的战舰数量,要查询的时候,我们只要知道i,j两号前面各有多少战舰,然后i前面的减去j前面的绝对值减一就可以了。

    而第一个指令就是简单地处理一下size,记录集合大小,也很简单

    AC代码

    #include <iostream>
    #include <cstdio>
    using namespace std;
    int f[30005];
    int d[30005];
    int size[30005];
    int t;
    int jdz(int x)
    {
    	return x>0? x:(-x);
    }
    void init()
    {
    	for(int i=1;i<=30000;i++)
    	{
    		f[i]=i;
    		size[i]=1;
    	}
    }
    int get(int x)
    {
    	if(x==f[x])
    	return x;
    	int root=get(f[x]);
    	d[x]+=d[f[x]];
    	return f[x]=root;
    }
    void merge(int x,int y)
    {
    	x=get(x),y=get(y);
    	f[x]=y;d[x]=size[y];
    	size[y]+=size[x];
    }
    int main()
    {
    	cin>>t;
    	init();
    	for(int i=1;i<=t;i++)
    	{
    		char s[2];
    		int x,y;
    		scanf("%s",s);
    		cin>>x>>y;
    		if(s[0]=='M')
    		merge(x,y);
    		if(s[0]=='C')
    		{
    			if(get(x)==get(y))
    			cout<<jdz(d[x]-d[y])-1<<endl;
    			else
    			cout<<"-1"<<endl;
    		}
    	}
    	return 0;
    }
    

    数据情况https://www.luogu.org/record/22153408

    本博文为wweiyi原创,若想转载请联系作者,qq:2844938982
  • 相关阅读:
    RocketMQ读书笔记3——消费者
    RocketMQ读书笔记1——简述
    02_dubbo实例_多版本号
    01_dubbo实例_服务分组
    分布式开放消息系统(RocketMQ)的原理与实践
    关于ajax的那些事
    关于html5之canvas的那些事
    关于js封装框架类库之属性操作
    关于js封装框架类库之样式操作
    关于js封装框架类库之事件模块
  • 原文地址:https://www.cnblogs.com/wweiyi2004/p/11300505.html
Copyright © 2011-2022 走看看