zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    设计模式---适配器模式
    【面经】2019-4-1 杭州边锋网络面经
    web前端基础——jQuery编程进阶
    web前端基础——jQuery编程基础
    web前端基础——初识HTML DOM编程
    web前端基础——初识JavaScript
    web前端基础——初识CSS
    web前端基础——初识HTML
    CentOS 6.5上安装python2.7、pip以及Python命令行补全和yum冲突解决
    Python中常用技巧整理
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5732732.html
Copyright © 2011-2022 走看看