zoukankan      html  css  js  c++  java
  • hdu-4292 Food(最大流)dinic

    Food

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 6598    Accepted Submission(s): 2238
    Problem Description
      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

    题意:一共有n个人f种食物,d种饮料,每个人对每种饮料和食物喜欢就是‘Y’,不喜欢是‘N’,求最多有几个人会满足。

    思路:最大流,拆人。

    这个题比较容易超时,好像一般都用了邻接表才能过。

    下面代码G++会超时,C++可以过。

    #include<map>
    #include<set>
    #include<queue>
    #include<math.h>
    #include <cstdio>
    #include <ctime>
    #include<vector>
    #include<string>
    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #define inf 0x3f3f3f3f
    #define ll long long
    #define OPT(_)(hip+(((_)-hip)^1))
    #define maxn 300000
    using namespace std;
    struct node  {
        int v,w;
        struct node *next;
    }hip[maxn],*hop;
    node *h[maxn];
    int d[maxn];
    int s,t;
    void w(int u,int v,int w,int b){
      hop->v=v;
      hop->w=w;
      hop->next=h[u];
      h[u]=hop++;
      hop->v=u;
      hop->w=b;
      hop->next=h[v];
      h[v]=hop++;
    }
    bool bfs(){
        queue<int>q;
        while(!q.empty())q.pop();
        memset(d,0,sizeof(d));
        d[s]=1;
        q.push(s);
        do{
            int u=q.front();
            q.pop();
            struct node*T;
            for(T=h[u];T!=NULL;T=T->next){
                if((T->w)>0&&d[T->v]==0){
                    d[T->v]=d[u]+1;
                    q.push(T->v);
                }
            }
        }while(!q.empty());
        if(d[t]==0)return false;
        else
            return true;
    }
    int  dfs(int u,int dist){
        if(u==t)
            return dist;
        struct node *p;
        for(p=h[u];p!=NULL;p=p->next){
            if((d[p->v]==d[u]+1)&&(p->w)>0){
                int di=dfs(p->v,min(dist,p->w));
                if(di>0){
                 p->w-=di;
                 OPT(p)->w+=di;
                 return di;
                }
            }
        }
        return 0;
    }
    int dinic(){
        int ans=0;
        while(bfs()){
            while(int d=dfs(s,inf)){
                ans+=d;}
        }
        return ans;}
    int main(){
        int n,f,d;
        while(~scanf("%d%d%d",&n,&f,&d)){
        s=0;t=n+n+d+f+1;
        memset(hip,0,sizeof(hip));
        hop=hip;
        for(int i=0;i<maxn;i++){h[i]=NULL;}
        for(int i=1;i<=f;i++){
            int x;scanf("%d",&x);w(s,i,x,0);
        }
        for(int i=1;i<=n;i++){
            w(f+i,f+n+i,1,0);
        }
        for(int i=1;i<=d;i++){
            int x;scanf("%d",&x);w(f+n+n+i,t,x,0);
        }
        for(int i=1;i<=n;i++){
            string s;cin>>s;
        for(int j=1;j<=f;j++){
            if(s[j-1]=='Y'){w(j,f+i,1,0);}}
        }
         for(int i=1;i<=n;i++){
            string s;cin>>s;
        for(int j=1;j<=d;j++){
            if(s[j-1]=='Y'){w(f+i+n,f+n+n+j,1,0);}}
        }
        cout<<dinic()<<endl;
      }
    }




     

  • 相关阅读:
    数论知识点--以及模板
    【数学+思维】ZZULIOJ 1531: 小L的区间求和
    记忆化搜索模板题---leetcode 1155. 掷骰子的N种方法
    拓扑排序
    ZOJ
    multiset的应用
    HDU
    HDU
    D. Beautiful Array
    HDU
  • 原文地址:https://www.cnblogs.com/da-mei/p/9053270.html
Copyright © 2011-2022 走看看