【BZOJ1854】[SCOI2010] 游戏(匈牙利算法的应用)

点此看题面

大致题意:\(n\)个物品,每个物品有两个属性且只能选择其中的一个,要求选择的物品属性值从\(1\)开始递增,问最多能选多少个。

暴搜

看到这题,我第一反应是暴搜... ...

好不容易过了样例,然后又调了半天,结果\(TLE\)了,只得了\(50\)分... ...

匈牙利算法

好吧,此题的正解是匈牙利算法,思想还是比较巧妙的。

建图

我们可以将每个物品的两个属性值作为左半部分的点,将每个物品作为右半部分的点,然后对于每个物品,将其两个属性与其编号连一条边。

然后就出现了一张二分图

匈牙利算法即可。

不过注意,此题不是求最大匹配,只要有一个属性值失配就需要立刻退出循环

代码

#include
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define uint unsigned int
#define LL long long
#define ull unsigned long long
#define swap(x,y) (x^=y,y^=x,x^=y)
#define abs(x) ((x)<0?-(x):(x))
#define INF 1e9
#define Inc(x,y) ((x+=(y))>=MOD&&(x-=MOD))
#define ten(x) (((x)<<3)+((x)<<1))
#define N 1000000
#define add(x,y) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y)
using namespace std;
int n,ans=0,ee=0,lnk[N+5];
struct edge
{
    int to,nxt;
}e[(N<<1)+5];
class FIO
{
    private:
        #define Fsize 100000
        #define tc() (FinNow==FinEnd&&(FinEnd=(FinNow=Fin)+fread(Fin,1,Fsize,stdin),FinNow==FinEnd)?EOF:*FinNow++)
        #define pc(ch) (FoutSize

转载于:https://www.cnblogs.com/chenxiaoran666/p/BZOJ1854.html

你可能感兴趣的:(【BZOJ1854】[SCOI2010] 游戏(匈牙利算法的应用))