zoukankan      html  css  js  c++  java
  • Food(最大流)

    Food

    http://acm.hdu.edu.cn/showproblem.php?pid=4292

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 8111    Accepted Submission(s): 2686


    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
     
    Source

    感觉和这题思路差不多:https://www.cnblogs.com/Fighting-sh/p/9818674.html

      1 #include<iostream>
      2 #include<cstring>
      3 #include<string>
      4 #include<cmath>
      5 #include<cstdio>
      6 #include<algorithm>
      7 #include<queue>
      8 #include<vector>
      9 #include<set>
     10 #define maxn 200005
     11 #define MAXN 200005
     12 #define mem(a,b) memset(a,b,sizeof(a))
     13 const int N=200005;
     14 const int M=200005;
     15 const int INF=0x3f3f3f3f;
     16 using namespace std;
     17 int n;
     18 struct Edge{
     19     int v,next;
     20     int cap,flow;
     21 }edge[MAXN*20];//注意这里要开的够大。。不然WA在这里真的想骂人。。问题是还不报RE。。
     22 int cur[MAXN],pre[MAXN],gap[MAXN],path[MAXN],dep[MAXN];
     23 int cnt=0;//实际存储总边数
     24 void isap_init()
     25 {
     26     cnt=0;
     27     memset(pre,-1,sizeof(pre));
     28 }
     29 void isap_add(int u,int v,int w)//加边
     30 {
     31     edge[cnt].v=v;
     32     edge[cnt].cap=w;
     33     edge[cnt].flow=0;
     34     edge[cnt].next=pre[u];
     35     pre[u]=cnt++;
     36 }
     37 void add(int u,int v,int w){
     38     isap_add(u,v,w);
     39     isap_add(v,u,0);
     40 }
     41 bool bfs(int s,int t)//其实这个bfs可以融合到下面的迭代里,但是好像是时间要长
     42 {
     43     memset(dep,-1,sizeof(dep));
     44     memset(gap,0,sizeof(gap));
     45     gap[0]=1;
     46     dep[t]=0;
     47     queue<int>q;
     48     while(!q.empty())
     49     q.pop();
     50     q.push(t);//从汇点开始反向建层次图
     51     while(!q.empty())
     52     {
     53         int u=q.front();
     54         q.pop();
     55         for(int i=pre[u];i!=-1;i=edge[i].next)
     56         {
     57             int v=edge[i].v;
     58             if(dep[v]==-1&&edge[i^1].cap>edge[i^1].flow)//注意是从汇点反向bfs,但应该判断正向弧的余量
     59             {
     60                 dep[v]=dep[u]+1;
     61                 gap[dep[v]]++;
     62                 q.push(v);
     63                 //if(v==sp)//感觉这两句优化加了一般没错,但是有的题可能会错,所以还是注释出来,到时候视情况而定
     64                 //break;
     65             }
     66         }
     67     }
     68     return dep[s]!=-1;
     69 }
     70 int isap(int s,int t)
     71 {
     72     if(!bfs(s,t))
     73     return 0;
     74     memcpy(cur,pre,sizeof(pre));
     75     //for(int i=1;i<=n;i++)
     76     //cout<<"cur "<<cur[i]<<endl;
     77     int u=s;
     78     path[u]=-1;
     79     int ans=0;
     80     while(dep[s]<n)//迭代寻找增广路,n为节点数
     81     {
     82         if(u==t)
     83         {
     84             int f=INF;
     85             for(int i=path[u];i!=-1;i=path[edge[i^1].v])//修改找到的增广路
     86                 f=min(f,edge[i].cap-edge[i].flow);
     87             for(int i=path[u];i!=-1;i=path[edge[i^1].v])
     88             {
     89                 edge[i].flow+=f;
     90                 edge[i^1].flow-=f;
     91             }
     92             ans+=f;
     93             u=s;
     94             continue;
     95         }
     96         bool flag=false;
     97         int v;
     98         for(int i=cur[u];i!=-1;i=edge[i].next)
     99         {
    100             v=edge[i].v;
    101             if(dep[v]+1==dep[u]&&edge[i].cap-edge[i].flow)
    102             {
    103                 cur[u]=path[v]=i;//当前弧优化
    104                 flag=true;
    105                 break;
    106             }
    107         }
    108         if(flag)
    109         {
    110             u=v;
    111             continue;
    112         }
    113         int x=n;
    114         if(!(--gap[dep[u]]))return ans;//gap优化
    115         for(int i=pre[u];i!=-1;i=edge[i].next)
    116         {
    117             if(edge[i].cap-edge[i].flow&&dep[edge[i].v]<x)
    118             {
    119                 x=dep[edge[i].v];
    120                 cur[u]=i;//常数优化
    121             }
    122         }
    123         dep[u]=x+1;
    124         gap[dep[u]]++;
    125         if(u!=s)//当前点没有增广路则后退一个点
    126         u=edge[path[u]^1].v;
    127      }
    128      return ans;
    129 }
    130 
    131 int a[maxn];
    132 int F[maxn],D[maxn];
    133 string mp[505];
    134 
    135 int main(){
    136     std::ios::sync_with_stdio(false);
    137     int m,s,t;
    138     int f,d;
    139     while(cin>>n>>f>>d){
    140         for(int i=1;i<=f;i++) cin>>F[i];
    141         for(int i=1;i<=d;i++) cin>>D[i];
    142         for(int i=1;i<=2*n;i++) cin>>mp[i];
    143         isap_init();
    144         s=0,t=n+n+f+d+1;
    145         for(int i=1;i<=n;i++){
    146             for(int j=0;j<f;j++){
    147                 if(mp[i][j]=='Y'){
    148                     add(j+1,f+i,1);
    149                 }
    150             }
    151         }
    152         for(int i=1;i<=n;i++){
    153             for(int j=0;j<d;j++){
    154                 if(mp[i+n][j]=='Y'){
    155                     add(f+n+i,f+n+n+j+1,1);
    156                 }
    157             }
    158         }
    159         for(int i=1;i<=n;i++) add(f+i,f+n+i,1);
    160         for(int i=1;i<=f;i++) add(s,i,F[i]);
    161         for(int i=1;i<=d;i++) add(f+n+n+i,t,D[i]);
    162         n=n+n+f+d+2;
    163         cout<<isap(s,t)<<endl;
    164     }
    165 }
    View Code
  • 相关阅读:
    CODING x 百果园 _ 水果零售龙头迈出 DevOps 体系建设第一步
    Nocalhost 亮相 CD Foundation 国内首届 Meetup,Keith Chan 将出席致辞
    做云原生时代标准化工具,实现高效云上研发工作流
    打造数字化软件工厂 —— 一站式 DevOps 平台全景解读
    WePack —— 助力企业渐进式 DevOps 转型
    CODING Compass —— 打造行云流水般的软件工厂
    Nocalhost —— 让云原生开发回归原始而又简单
    CODING 代码资产安全系列之 —— 构建全链路安全能力,守护代码资产安全
    Nocalhost:云原生开发新体验
    使用 Nocalhost 开发 Kubernetes 中的 APISIX Ingress Controller
  • 原文地址:https://www.cnblogs.com/Fighting-sh/p/9951565.html
Copyright © 2011-2022 走看看