[bzoj1854][Scoi2010]游戏

有n个装备,每个装备都可以选择一种属性值(1<=ai<=10000),每种装备只能选择一种属性值,只能攻击一次,造成伤害等于属性值。你要从1开始造成伤害,造成的伤害每次+1,求最多能造成多少伤害。  n<=1000000

题解:二分图匹配,直接上匈牙利就好啦。注意要先走小的那一侧,复杂度才靠谱。

#include<iostream>
#include<cstdio> 
#include<algorithm>
#include<cmath>
#define MN 1010000
#define MM 10000
using namespace std;
inline int read()
{
    int x = 0 , f = 1; char ch = getchar();
    while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
    return x * f;
}

struct edge{int to,next;}e[MN*5];
int n,m,now;
int mark[MN+5],cnt=0,head[MN+5],mat[MN+5];

inline void ins(int f,int t){e[++cnt]=(edge){t,head[f]};head[f]=cnt; }

bool dfs(int x)
{
    mark[x]=now;
    for(int i=head[x];i;i=e[i].next)
        if(mark[e[i].to]!=now)
        {
            mark[e[i].to]=now;
            if(!mat[e[i].to]||dfs(mat[e[i].to])) 
                return mat[e[i].to]=x,mat[x]=e[i].to,true;
        }
    return false;
}

int main()
{
    n=read();
    for(int i=1;i<=n;i++)
    {
        int x=read(),y=read();
        ins(x,i+MM);ins(y,i+MM);
    }
    for(now=1;now<=10000;now++)
        if(!dfs(now)) return 0*printf("%d
",now-1);
    puts("10000");
    return 0;
}
原文地址:https://www.cnblogs.com/FallDream/p/bzoj1854.html