您的位置:首页 > 其它

【BZOJ】1854【Scoi2010】游戏

2016-07-20 17:48 232 查看
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 最多能连续攻击的次数。

SampleInput

3

1 2

3 2

4 5

SampleOutput

2

HINT

【数据范围】

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

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

Source

Day1

Solution

这题有并查集做法,见黄学长博客。

传送门http://hzwer.com/2950.html

如果不嫌我方法麻烦就看下去吧。

因为攻击一次需要一个装备,即我们最后求得的是一个第k 次攻击与装备的匹配关系。

不能跳过某次攻击,也就是说,我们要得到一个攻击次数从小到大全部(最多)能与装备匹配的方案。

那么思路就很清晰了,每一个匹配边表示使用某个装备解决某次攻击。

要求的就是从一开始连续能匹配掉多少个属性值。

首先这是个二分图,然后匈牙利在匹配时不会使之前已经匹配的左子图(即开始搜索的子图)点失配。

所以第几次攻击与武器连边,匈牙利解决。

#include<cstdio>
#include<cstring>
#define M 1020000

using namespace std;

struct edge{int v,n;}e[M<<2];
int link[M],n,x,y,tot,s[M],t=1,time[M];

bool dfs(int u)
{
for(int i=s[u];i;i=e[i].n)
{
int v=e[i].v;
if(time[v]!=t)
{
time[v]=t;
if(link[v]==0 || dfs(link[v]))
{
link[v]=u;
return 1;
}
}
}
return 0;
}

inline void push(const int &u,const int &v){e[++tot].v=v;e[tot].n=s[u];s[u]=tot;}

int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d%d",&x,&y);
push(i,x+n);push(i,y+n);push(x+n,i);push(y+n,i);
}
for (int i=n+1;i<=n+10000;i++,t++)
{
time[i]=t;
if (!dfs(i))
{
printf("%d",i-n-1);
return 0;
}
}
puts("10000");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: