Food(拆点建图,网络流)

  You, a part-time dining service worker in your college’s dining hall, are now confused with a new problem: serve as many people as possible.
  The issue comes up as people in your college are more and more difficult to serve with meal: They eat only some certain kinds of food and drink, and with requirement unsatisfied, go away directly.
  You have prepared F (1 <= F <= 200) kinds of food and D (1 <= D <= 200) kinds of drink. Each kind of food or drink has certain amount, that is, how many people could this food or drink serve. Besides, You know there’re N (1 <= N <= 200) people and you too can tell people’s personal preference for food and drink.
  Back to your goal: to serve as many people as possible. So you must decide a plan where some people are served while requirements of the rest of them are unmet. You should notice that, when one’s requirement is unmet, he/she would just go away, refusing any service.

 
Input
  There are several test cases.
  For each test case, the first line contains three numbers: N,F,D, denoting the number of people, food, and drink.
  The second line contains F integers, the ith number of which denotes amount of representative food.
  The third line contains D integers, the ith number of which denotes amount of representative drink.
  Following is N line, each consisting of a string of length F. �e jth character in the ith one of these lines denotes whether people i would accept food j. “Y” for yes and “N” for no.
  Following is N line, each consisting of a string of length D. �e jth character in the ith one of these lines denotes whether people i would accept drink j. “Y” for yes and “N” for no.
  Please process until EOF (End Of File).
 
Output
  For each test case, please print a single line with one integer, the maximum number of people to be satisfied.
 
Sample Input
4 3 3 1 1 1 1 1 1 YYN NYY YNY YNY YNY YYN YYN NNY
 
Sample Output
3
 
Source
 
Recommend
liuyiding   |   We have carefully selected several similar problems for you:  4288 4296 4295 4294 4293 
 
把每个人拆成一条容量为1的边,这样保证了人之间流量最多为1。
然后根据匹配连,饮料在左侧,连源点,食物在右侧,连汇点。
#include <bits/stdc++.h>
#define maxn 10005
using namespace std;
struct Person
{
    string food,drink;
}person[maxn];
const int inf= 1e9;
struct Edge
{
    int u,v,c,flow;
    Edge(int a,int b,int cc,int f):u(a),v(b),c(cc),flow(f){}
};
struct Dinic
{
    int s,t;
    vector<Edge> edges;
    vector<int> pre[maxn];
    bool vis[maxn];
    int dist[maxn];
    int cur[maxn];
    void init()
    {
        for(int i=0;i<maxn;i++)
        {
            pre[i].clear();
        }
        edges.clear();
    }
    void Addedge(int u,int v,int f)
    {
        edges.push_back(Edge(u,v,f,0));
        edges.push_back(Edge(v,u,0,0));
        int mm=edges.size();
        pre[u].push_back(mm-2);
        pre[v].push_back(mm-1);
    }
    bool bfs()
    {
        memset(vis,false,sizeof(vis));
        queue<int> q;
        q.push(s);
        vis[s]=1;
        dist[s]=0;
        while(!q.empty())
        {
            int now=q.front();
            q.pop();
            for(int i=0;i<pre[now].size();i++)
            {
                Edge &e=edges[pre[now][i]];
                if(!vis[e.v]&&e.c>e.flow)
                {
                    dist[e.v]=dist[now]+1;
                    vis[e.v]=true;
                    q.push(e.v);
                }
            }
        }
        return vis[t];
    }
    int dfs(int x,int cap)
    {
        if(x==t||cap==0) return cap;
        int f,flow=0;
        for(int &i=cur[x];i<pre[x].size();i++)
        {
            cur[x]=i;
            Edge &e=edges[pre[x][i]];
            if(dist[e.v]==dist[x]+1&&(f=dfs(e.v,min(cap,e.c-e.flow))))
               {
                   e.flow+=f;
                    edges[pre[x][i]^1].flow-=f;
            flow+=f;
            cap-=f;
            if(cap==0) break;
               }
        }
        return flow;
    }
    int Maxflow(int s,int t)
    {
        this->s=s;
        this->t=t;
        int flow=0;
        while(bfs())
        {
            memset(cur,0,sizeof(cur));
            flow+=dfs(s,inf);
        }
        return flow;
    }
}dc;
int main()
{
    int n,f,d,i;
    while(cin>>n>>f>>d)
    {
        dc.init();
    int a[maxn]={0};
    int b[maxn]={0};
        for(i=1;i<=f;i++)
    {
        scanf("%d",&a[i]);
    }
    for(i=1;i<=d;i++)
    {
        scanf("%d",&b[i]);
    }
    for(i=1;i<=n;i++)
    {
        cin>>person[i].food;
    }
    for(i=1;i<=n;i++)
    {
        cin>>person[i].drink;
    }
    for(i=1;i<=n;i++)
    {
        for(int j=0;j<f;j++)
        {
            if(person[i].food[j]=='Y')
            {
                dc.Addedge(j+1,f+i,1);
            }
        }
    }
    for(i=1;i<=n;i++)
    {
        dc.Addedge(f+i,f+n+i,1);
    }
    for(i=1;i<=n;i++)
    {
        for(int j=0;j<d;j++)
        {
            if(person[i].drink[j]=='Y')
            {
                dc.Addedge(f+n+i,f+2*n+j+1,1);
            }
        }
    }
    for(i=1;i<=f;i++)
    {
        dc.Addedge(0,i,a[i]);
    }
    for(i=1;i<=d;i++)
    {
        dc.Addedge(f+2*n+i,f+2*n+d+1,b[i]);
    }
    printf("%d
",dc.Maxflow(0,f+2*n+d+1));
    }
    return 0;
}

  

 
原文地址:https://www.cnblogs.com/zyf3855923/p/9458745.html