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
  • 相关阅读:
    Linux基础-文件管理
    Linux基础-命令概述
    linux基础--目录介绍
    Cookie和Session(session过程和设置进程外session)
    [CSP-S2020]儒略日 题解
    [NOI2020]制作菜品 题解
    [NOI2020]命运 题解
    CSP-S2020 游记
    2020年泉州市信息学国庆模拟赛(提高组) 题解
    luogu4241 采摘毒瘤 题解
  • 原文地址:https://www.cnblogs.com/wweiyi2004/p/11300505.html
Copyright © 2011-2022 走看看