• 洛谷 P1640 SCOI2010 连续攻击游戏 并查集


    题目描述

    lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示。当他使用某种装备时,他只能使用该装备的某一个属性。并且每种装备最多只能使用一次。游戏进行到最后,lxhgww遇到了终极boss,这个终极boss很奇怪,攻击他的装备所使用的属性值必须从1开始连续递增地攻击,才能对boss产生伤害。也就是说一开始的时候,lxhgww只能使用某个属性值为1的装备攻击boss,然后只能使用某个属性值为2的装备攻击boss,然后只能使用某个属性值为3的装备攻击boss……以此类推。现在lxhgww想知道他最多能连续攻击boss多少次?

    输入格式

    输入的第一行是一个整数N,表示lxhgww拥有N种装备接下来N行,是对这N种装备的描述,每行2个数字,表示第i种装备的2个属性值

    输出格式

    输出一行,包括1个数字,表示lxhgww最多能连续攻击的次数。

    输入输出样例

    输入样例

    3
    1 2
    3 2
    4 5
    

    输出样例

    2
    

    说明/提示

    Limitation

    对于30%的数据,保证N < =1000

    对于100%的数据,保证N < =1000000

    分析

    先来一个水过的代码

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    int ma[1000000];
    int main(){
    	int n;
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++){
    		int aa,bb;
    		scanf("%d%d",&aa,&bb);
    		if(ma[aa]) ma[bb]++;
    		else if(ma[bb]) ma[aa]++;
    		else ma[min(aa,bb)]++;
    	}
    	for(int i=1;i<=1000001;i++){
    		if(!ma[i]){
    			printf("%d
    ",i-1);
    			return 0;
    		}
    	}
    	return 0;
    }
    

    思路大致是读入两个值后,如果有一个在之前已经选过了,那么选另一个,如果都没选过,就挑一个较小的选,要是都选过,就随便选

    但是这样显然是不太正确的,比如下面这组数据

    4

    3 2

    4 1

    3 1

    2 2

    正解应该是4,但上面的代码却输出3

    正解需要用并查集来解决

    每次读入装备的两个值后,如果两个值的祖先节点不相等,我们就将这两个值的祖先节点并在一起,用值较大的祖先节点作为父亲节点,同时将值较小的祖先节点标记为访问过;如果两个值的祖先节点相等,那么我们就将这个祖先节点标记为访问过

    那么这种做法和上面的做法区别在哪里呢

    其实就是在数据的处理上,比如上面的第二个装备4 1

    第一种方法会直接把4丢掉,而第二种方法则会把4记录下来,以为它还有可能对后面的答案做出贡献

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int n,m,fa[1000005];
    bool vis[1000005];
    int zhao(int xx){
        if(xx==fa[xx]) return xx;
        return fa[xx]=zhao(fa[xx]);
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=1000000;i++) fa[i]=i;
        for(int i=1;i<=n;i++){
            int aa,bb;
            scanf("%d%d",&aa,&bb);
            int xx=zhao(aa),yy=zhao(bb);
            if(xx==yy)vis[xx]=1;
            else {
                if(xx<yy)swap(xx,yy);
                fa[yy]=xx,vis[yy]=1;
            }
        }
        for(int i=1;i<=n+1;i++){
            if(!vis[i]){
                printf("%d
    ",i-1);
                break;
            }
        }
        return 0;
    }
    
  • 相关阅读:
    sitecore系统教程之体验编辑器
    Sitecore安装(手动方式)
    Sitecore详细安装(包含sitecore安装过程截图)
    logstash快速入门实战指南-Logstash简介
    Elasticsearch从入门到精通之Elasticsearch基本概念
    arcgis api 3.x for js 解决 textSymbol 文本换行显示(附源码下载)
    openlayers4 入门开发系列之前端动态渲染克里金插值 kriging 篇(附源码下载)
    arcgis api 4.x for js 结合 react 入门开发系列react全家桶实现加载天地图(附源码下载)
    arcgis api 4.x for js 结合 react 入门开发系列"esri-loader"篇(附源码下载)
    arcgis api 4.x for js 结合 react 入门开发系列初探篇(附源码下载)
  • 原文地址:https://www.cnblogs.com/liuchanglc/p/12822739.html
Copyright © 2020-2023  润新知