AC日记——[SCOI2010]游戏 bzoj 1854
1854: [Scoi2010]游戏
Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 4938 Solved: 1948
[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
1 2
3 2
4 5
Sample Output
2
HINT
【数据范围】
对于30%的数据,保证N < =1000
对于100%的数据,保证N < =1000000
Source
思路:
这题的并查集做法简直逆天;
通过并查集把可能重复的属性都给链接到一块;
然后就开始进行合并判断哪些属性能用到;
然后从1开始到10000遍历;
哪个属性是false(没被合并)最大就是到那;
来,上代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define maxn 100005 using namespace std; int n,f[maxn]; bool if_[maxn]; char Cget; inline void in(int &now) { now=0,Cget=getchar(); while(Cget>'9'||Cget<'0') Cget=getchar(); while(Cget>='0'&&Cget<='9') { now=now*10+Cget-'0'; Cget=getchar(); } return ; } int find(int x) { if(x==f[x]) return x; f[x]=find(f[x]); return f[x]; } int main() { freopen("game.in","r",stdin); freopen("game.out","w",stdout); in(n);int x,y; for(int i=1;i<=10000;i++) f[i]=i; for(int i=1;i<=n;i++) { in(x),in(y); x=find(x),y=find(y); if(x==y) if_[x]=true; else { if(x>y) swap(x,y); f[x]=y; if_[x]=true; } } for(int i=1;i<=10001;i++) { if(!if_[i]) { printf("%d\n",i-1); break; } } return 0; fclose(stdin); fclose(stdout); }