【BZOJ】1854【Scoi2010】游戏

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%  的数据,保证 N1000 
对于 100%  的数据,保证 N1000000 

Source 

Day1 

Solution 

这题有并查集做法,见黄学长博客。
传送门http://hzwer.com/2950.html
如果不嫌我方法麻烦就看下去吧。

因为攻击一次需要一个装备,即我们最后求得的是一个第 k  <script id="MathJax-Element-1078" type="math/tex">k</script>次攻击与装备的匹配关系。

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

那么思路就很清晰了,每一个匹配边表示使用某个装备解决某次攻击。
要求的就是从一开始连续能匹配掉多少个属性值。

首先这是个二分图,然后匈牙利在匹配时不会使之前已经匹配的左子图(即开始搜索的子图)点失配。
所以第几次攻击与武器连边,匈牙利解决。

#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");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值