考虑到问题

能使最多顾客满意呢

所以我们应以客人为主要限制目标,所以将其放中间,两边各连房间和菜,于是便可转化为最大流问题

建图应注意到客人只要一个,所以对每个客人应建两点,相连的权值为1,左边点与房间相连,右边点与菜相连

const int N = 2e5 + 86;

struct egdes
{
    int to, nxt, w;
} e[N * 2];
int hd[N * 2], cur[N * 2], tot = 1, st, en;
vi lv;
void add(int x, int y, int w)
{
    e[++tot] = (egdes){y, hd[x], w};
    hd[x] = tot;
}

int bfs()
{
    lv.assign(N, 0);
    memcpy(cur, hd, sizeof(hd));
    queue<int> q;
    q.push(st);
    lv[st] = 1;
    while (!q.empty())
    {
        int p = q.front();
        q.pop();
        for (int eg = hd[p]; eg; eg = e[eg].nxt)
        {
            int to = e[eg].to, vol = e[eg].w;
            if (vol && !lv[to])
            {
                lv[to] = lv[p] + 1;
                q.push(to);
            }
        }
    }
    return lv[en];
}

int dfs(int ss, int flow)
{
    if (ss == en)
        return flow;
    int r = flow;
    for (int eg = cur[ss]; eg && r; eg = e[eg].nxt)
    {
        cur[ss] = eg;
        int to = e[eg].to, vol = e[eg].w;
        if (vol && lv[to] == lv[ss] + 1)
        {
            int c = dfs(to, min(r, vol));
            r -= c;
            e[eg].w -= c;
            e[eg ^ 1].w += c;
        }
    }
    return flow - r;
}
int rs, fj, cai;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> rs>>fj>>cai;
    st=rs+fj+cai+4,en=st+1;
    f(i,1,cai){
        add(st,i,1);
        add(i,st,0);
    }
    f(i,1,fj){
        add(rs+cai+i,en,1);
        add(en,rs+cai+i,0);
    }
    f(i,1,rs){
        add(cai+i,en+i,1);
        add(en+i,cai+i,0);
    }
    f(i, 1, rs)
    {
        f(j, 1, fj)
        {
            int x;
            cin >> x;
            if (x)
            {
                add(en+i,cai+rs+j,1);
                add(cai+rs+j,en+i,0);
            }
        }
    }
    f(i, 1,rs)
    {
        f(j, 1, cai)
        {
            int x;
            cin >> x;
            if (x)
            {
                add(j,cai+i,1);
                add(cai+i,j,0);
            }
        }
    }
    LL ans=0;
    while(bfs()){
        ans+=dfs(st,3e8);
    }
    cout<<ans;
    return 0;
}
此文章已被阅读次数:正在加载...更新于