• bzoj1854[Scoi2010]游戏


    bzoj1854[Scoi2010]游戏

    题意:

    n个装备,每种装备都有2个属性值,分别用[1,10000]之间的数表示。使用某种装备时,只能使用该装备的某一个属性。并且每种装备最多只能使用一次。攻击boss的装备所使用的属性值必须从1开始连续递增地攻击,才能对boss产生伤害。求最多能连续攻击boss多少次。

    题解:

    本题竟然用并查集!把每个装备看成1条无向边,当n条边没有组成一个环时,则一共可以得到n-1个属性,如果n条边组成了一个环,则可以得到n个属性。因此可以使用并查集,根据它除了并操作不会改变根节点的性质,用它维护一个vis数组表示第i个属性能否得到,当一条边插入时,如果两个端点不在一个联通块中,就将根节点表示属性小的那个联通块连到大的那个,并将小的联通块根节点的vis置为1,大的不变;如果在一个联通块中,就将该联通块根节点vis置为1。最后枚举一下vis从1到多少均为1就是答案。

    注意:因为我的程序是枚举到vis为0的那个值退出,由于属性最大是10000,所以要枚举到10001。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define inc(i,j,k) for(int i=j;i<=k;i++)
     5 using namespace std;
     6 
     7 bool vis[20000]; int fa[20000],n;
     8 int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
     9 int main(){
    10     scanf("%d",&n); inc(i,1,10000)fa[i]=i; memset(vis,0,sizeof(vis));
    11     inc(i,1,n){
    12         int a,b,x,y; scanf("%d%d",&a,&b); x=find(a); y=find(b);
    13         if(x==y)vis[x]=1;else{if(x>y)swap(x,y); fa[x]=y; vis[x]=1;}
    14     }
    15     inc(i,1,10001)if(!vis[i]){printf("%d",i-1); break;}
    16     return 0;
    17 }

    20160520

  • 相关阅读:
    qs.js库 使用方法
    Python的装饰器
    Html常用标记总结
    SoapUI、Jmeter、Postman三种接口测试工具的比较
    WebService发布协议--SOAP和REST的区别
    Redis简介
    linux搭建svn服务并手动同步代码到web目录和自动更新
    标签有关用法以及锚点定位;
    DevOps简单介绍
    BAT 批处理脚本教程
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5732732.html
Copyright © 2020-2023  润新知