P1402 酒店之王 网络流

大水题,我自己瞎做就做出来了,没啥说的,zz建图,就是板子。

题干:

题目描述

XX酒店的老板想成为酒店之王,本着这种希望,第一步要将酒店变得人性化。由于很多来住店的旅客有自己喜好的房间色调、阳光等,也有自己所爱的菜,但是该酒店只有p间房间,一天只有固定的q道不同的菜。

有一天来了n个客人,每个客人说出了自己喜欢哪些房间,喜欢哪道菜。但是很不幸,可能做不到让所有顾客满意(满意的条件是住进喜欢的房间,吃到喜欢的菜)。

这里要怎么分配,能使最多顾客满意呢?
输入输出格式
输入格式:

第一行给出三个正整数表示n,p,q(<=100)。

之后n行,每行p个数包含0或1,第i个数表示喜不喜欢第i个房间(1表示喜欢,0表示不喜欢)。

之后n行,每行q个数,表示喜不喜欢第i道菜。

输出格式:

最大的顾客满意数。

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(register int i = a;i <= n;++i)
#define lv(i,a,n) for(register int i = a;i >= n;--i)
#define clean(a) memset(a,0,sizeof(a))
const int INF = 1 << 30;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
    char c;
    bool op = 0;
    while(c = getchar(), c < '0' || c > '9')
        if(c == '-') op = 1;
    x = c - '0';
    while(c = getchar(), c >= '0' && c <= '9')
        x = x * 10 + c - '0';
    if(op) x = -x;
}
template <class T>
void write(T x)
{
    if(x < 0) putchar('-'), x = -x;
    if(x >= 10) write(x / 10);
    putchar('0' + x % 10);
}
const int N = 1e3 + 5;
struct node
{
    int l,r,nxt,w,oth;
}a[N * 10];
int len = 0,lst[N];
void add(int x,int y,int w)
{
//    cout<<x<<" "<<y<<" "<<w<<endl;
    int k1,k2;
    a[++len].l = x;
    a[len].r = y;
    a[len].w = w;
    a[len].nxt = lst[x];
    lst[x] = len;
    k1 = len;
    a[++len].l = y;
    a[len].r = x;
    a[len].w = 0;
    a[len].nxt = lst[y];
    lst[y] = len;
    k2 = len;
    a[k1].oth = k2;
    a[k2].oth = k1;
}
int n,p,q;
int h[N],ed = 0;
bool bfs()
{
    clean(h);
    h[0] = 1;
    queue <int> q;
    q.push(0);
    while(!q.empty())
    {
        int x = q.front();
        q.pop();
        for(int k = lst[x];k != -1;k = a[k].nxt)
        {
            int y = a[k].r;
            if(a[k].w > 0 && h[y] == 0)
            {
                h[y] = h[x] + 1;
                q.push(y);
            }
        }
    }
    if(h[ed] > 0)
    return true;
    else
    return false;
}
int find(int x,int f)
{
    if(x == ed)
    {
        return f;
    }
    int s = 0,t;
    for(int k = lst[x];k != -1;k = a[k].nxt)
    {
        int y = a[k].r;
        if(s < f && h[y] == h[x] + 1 && a[k].w > 0)
        {
            t = find(y,min(a[k].w,f - s));
            s += t;
            a[k].w -= t;
            a[a[k].oth].w += t;
        }
    }
    if(s == 0)
    h[x] = 0;
    return s;
}
int main()
{
    read(n);read(p);read(q);
    memset(lst,-1,sizeof(lst));
    duke(i,1,n)
    add(0,i,1);
    duke(i,1,n)
    {
        duke(j,1,p)
        {
            int x;
            read(x);
            if(x == 1)
            {
                add(j,p + i,1);
            }
        }
    }
    duke(i,1,n)
    {
        add(p + i,p + n + i,1);
    }
    duke(i,1,n)
    {
        duke(j,1,p)
        {
            int x;
            read(x);
            if(x == 1)
            {
                add(p + n + i,p + 2 * n + j,1);
            }
        }
    }
    ed = 2 * p + 2 * n + 1;
    duke(i,1,p)
    {
        add(p + 2 * n + i,ed,1);
    }
    int s = 0,t,l;
    while(bfs() == true)
    {
        s += find(0,INF);
    }
    printf("%d\n",s);
    return 0;
}

 

上一篇:SAM入门


下一篇:P2351 [SDOi2012]吊灯