zoukankan      html  css  js  c++  java
  • hdu 4292 Food 最大流

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4292

    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.

    题意描述:你准备了F种食物(F<=200)和D种饮料(D<=200),每种食物和饮料都有一定的数量。有n个人(n<=200),每个人都有喜欢的食物和饮料并且只能吃自己喜欢的食物、喝喜欢的饮料,求出能够吃到喜欢的食物并喝到喜欢的饮料的最大人数。

    算法分析:运用网络最大流求解即可。新增源点from和汇点to,from->食物(w为食物数量),饮料->to(w为饮料数量),对每个人 i 拆边 i 和 i+n ,喜欢的食物->i(w为1),i -> i+n(w为1),i+n->喜欢的饮料(w为1)。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cstdlib>
      5 #include<cmath>
      6 #include<algorithm>
      7 #include<vector>
      8 #include<queue>
      9 #define inf 0x7fffffff
     10 using namespace std;
     11 const int maxn=200+10;
     12 const int M = 999999;
     13 
     14 int n,F,D;
     15 int from,to,d[maxn*10];
     16 struct node
     17 {
     18     int v,flow;
     19     int next;
     20 }edge[M*2];
     21 int head[maxn*10],edgenum;
     22 
     23 void add(int u,int v,int flow)
     24 {
     25     edge[edgenum].v=v ;edge[edgenum].flow=flow;
     26     edge[edgenum].next=head[u];
     27     head[u]=edgenum++;
     28 
     29     edge[edgenum].v=u ;edge[edgenum].flow=0;
     30     edge[edgenum].next=head[v];
     31     head[v]=edgenum++;
     32 }
     33 
     34 int bfs()
     35 {
     36     memset(d,0,sizeof(d));
     37     d[from]=1;
     38     queue<int> Q;
     39     Q.push(from);
     40     while (!Q.empty())
     41     {
     42         int u=Q.front() ;Q.pop() ;
     43         for (int i=head[u] ;i!=-1 ;i=edge[i].next)
     44         {
     45             int v=edge[i].v;
     46             if (!d[v] && edge[i].flow>0)
     47             {
     48                 d[v]=d[u]+1;
     49                 Q.push(v);
     50                 if (v==to) return 1;
     51             }
     52         }
     53     }
     54     return 0;
     55 }
     56 
     57 int dfs(int u,int flow)
     58 {
     59     if (u==to || flow==0) return flow;
     60     int cap=flow;
     61     for (int i=head[u] ;i!=-1 ;i=edge[i].next)
     62     {
     63         int v=edge[i].v;
     64         if (d[v]==d[u]+1 && edge[i].flow>0)
     65         {
     66             int x=dfs(v,min(cap,edge[i].flow));
     67             cap -= x;
     68             edge[i].flow -= x;
     69             edge[i^1].flow += x;
     70             if (cap==0) return flow;
     71         }
     72     }
     73     return flow-cap;
     74 }
     75 
     76 int dinic()
     77 {
     78     int sum=0;
     79     while (bfs()) sum += dfs(from,inf);
     80     return sum;
     81 }
     82 
     83 int main()
     84 {
     85     while (scanf("%d%d%d",&n,&F,&D)!=EOF)
     86     {
     87         memset(head,-1,sizeof(head));
     88         edgenum=0;
     89         from=F+2*n+D+1;
     90         to=from+1;
     91         int a;
     92         for (int i=1 ;i<=F ;i++)
     93         {
     94             scanf("%d",&a);
     95             add(from,i,a);
     96         }
     97         for (int i=1 ;i<=D ;i++)
     98         {
     99             scanf("%d",&a);
    100             add(F+2*n+i,to,a);
    101         }
    102         char str[maxn];
    103         memset(str,0,sizeof(str));
    104         for (int i=1 ;i<=n ;i++)
    105         {
    106             scanf("%s",str+1);
    107             for (int j=1 ;j<=F ;j++)
    108             {
    109                 if (str[j]=='Y')
    110                     add(j,F+i,1);
    111             }
    112         }
    113         for (int i=1 ;i<=n ;i++)
    114         {
    115             scanf("%s",str+1);
    116             for (int j=1 ;j<=D ;j++)
    117             {
    118                 if (str[j]=='Y')
    119                     add(F+n+i,F+2*n+j,1);
    120             }
    121         }
    122         for (int i=1 ;i<=n ;i++)
    123             add(F+i,F+n+i,1);
    124         printf("%d
    ",dinic());
    125     }
    126     return 0;
    127 }

     

  • 相关阅读:
    MongoDB+模板引擎 项目实例-学生档案管理
    MongoDB 增删改查命令速查
    MongoDB 数据库概述及环境搭建
    Flutter 升级
    TypeScript 快速上手及学习笔记
    Android ContentProvider 启动分析
    HTTP 报文格式简介
    深入浅出 HTTPS (详解版)
    从你输入网址,到看到网页——详解中间发生的过程
    TCP 三次握手和四次挥手图解(有限状态机)
  • 原文地址:https://www.cnblogs.com/huangxf/p/4324636.html
Copyright © 2011-2022 走看看