• BZOJ 1854 Scoi2010 游戏


    1854: [Scoi2010]游戏
    
    Time Limit: 5 Sec  Memory Limit: 162 MB
    Submit: 5930  Solved: 2396
    [Submit][Status][Discuss]
    Description
    
    lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示。当他使用某种装备时,他只能使用该装备的某一个属性。并且每种装备最多只能使用一次。 游戏进行到最后,lxhgww遇到了终极boss,这个终极boss很奇怪,攻击他的装备所使用的属性值必须从1开始连续递增地攻击,才能对boss产生伤害。也就是说一开始的时候,lxhgww只能使用某个属性值为1的装备攻击boss,然后只能使用某个属性值为2的装备攻击boss,然后只能使用某个属性值为3的装备攻击boss……以此类推。 现在lxhgww想知道他最多能连续攻击boss多少次?
    Input
    
    输入的第一行是一个整数N,表示lxhgww拥有N种装备 接下来N行,是对这N种装备的描述,每行2个数字,表示第i种装备的2个属性值
    Output
    
    输出一行,包括1个数字,表示lxhgww最多能连续攻击的次数。
    Sample Input
    
    3
    
    1 2
    
    3 2
    
    4 5
    
    Sample Output
    
    2
    
    HINT
    
    【数据范围】
    对于30%的数据,保证N < =1000
    对于100%的数据,保证N < =1000000
    Source
    
    Day1
    
    [
    题目

    数据太水,应该可以用二分图写过吧

    正解是并查集,如果我们让每个装备的两个属性值之间连无向边的时候,如果出现了环那么环上的每一个点都可以选

    如果不构成环,那么要有一个点不被选,我们选择权值最大的那个,接下来就简单了,但我们每加一条边的时候

    判断是否在同一个并查集里如果不在的话,我们让权值大的那个作为祖先

    那么说明构成环,我们直接让他的祖先可以选,为什么呢,因为在不是环之前,只有祖先没有选,现在构成环了,就可以让祖先选了

    复杂度 大约是n*(维护并查集的常数),比二分图要优秀的多

    代码:

     1 #include <bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 inline int read(){
     5     int x=0;int f=1;char ch=getchar();
     6     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
     7     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
     8     return x*f;
     9 }
    10 const int MAXN=1e6+10;
    11 int fa[MAXN],n,vis[MAXN]={};
    12 inline int getfather(int xx){
    13     return fa[xx]==xx?xx:fa[xx]=getfather(fa[xx]);
    14 }
    15 int main(){
    16     freopen("All.in","r",stdin);
    17     freopen("a.out","w",stdout);
    18     n=read();
    19     for(int i=1;i<=10010;i++){
    20         fa[i]=i;
    21     }
    22     for(int i=1;i<=n;i++){
    23         int xx=read();int yy=read();
    24         int gx=getfather(xx);int gy=getfather(yy);
    25         if(gx==gy){
    26             vis[gx]=1;
    27         }
    28         else{
    29             if(gx>gy) swap(gx,gy);
    30             fa[gx]=gy;
    31             vis[gx]=1;
    32         }    
    33     }
    34     int sum=0;
    35         for(int i=1;i<=10000;i++){
    36             if(vis[i]) sum++;
    37             else break;
    38         }
    39         cout<<sum<<endl;
    40         return 0;
    41 }
    View Code
  • 相关阅读:
    while循环学习之统计流量
    MySQL的启动脚本
    UVA 725 Division
    UVA 712 S-tree
    UVA 514
    字典树
    UVA 1595 multimap 的应用
    C++ map 和 multimap
    浮点数
    UVA 227
  • 原文地址:https://www.cnblogs.com/something-for-nothing/p/7856812.html
Copyright © 2020-2023  润新知