HDU 4292 Food 多源多汇入门题

                    Food

有F种食物和D种饮料,每种食物或饮料只能供有限次,且每个人只享用一种食物和一种饮料。现在有n个人,每个人都有自己喜欢的食物种类列表和饮料种类列表,问最多能使几个人同时享用到自己喜欢的食物和饮料。

邻接矩阵 DINIC    在定点数较多的时候比较慢。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <algorithm>
  6 #include <string>
  7 #include <vector>
  8 #include <set>
  9 #include <map>
 10 #include <stack>
 11 #include <queue>
 12 #include <sstream>
 13 #include <iomanip>
 14 using namespace std;
 15 typedef long long LL;
 16 const int INF = 0x4fffffff;
 17 const double EXP = 1e-5;
 18 const int MS = 205;
 19 const int SIZE = 100005;
 20
 21 int edges[4*MS][4*MS];
 22 int level[4*MS];
 23 int que[6*MS];
 24 char str[MS];
 25 int qs,qe;
 26 int n,f,d,cnt;
 27
 28 bool BFS()
 29 {
 30       memset(level,0xff,sizeof(level));
 31       level[0]=0;
 32       qs=qe=0;
 33       que[qe++]=0;
 34       while(qs<qe)
 35       {
 36             int u=que[qs++];
 37             for(int v=0;v<=cnt;v++)
 38             {
 39                   if(level[v]<0&&edges[u][v]>0)
 40                   {
 41                         level[v]=level[u]+1;
 42                         que[qe++]=v;
 43                   }
 44             }
 45       }
 46       return level[cnt]>0;
 47 }
 48
 49 int DFS(int u,int minv)
 50 {
 51       if(u==cnt)
 52             return minv;
 53       int t;
 54       for(int v=0;v<=cnt;v++)
 55       {
 56             if(edges[u][v]>0&&level[v]==level[u]+1&&(t=DFS(v,min(minv,edges[u][v]))))
 57             {
 58                   edges[u][v]-=t;
 59                   edges[v][u]+=t;
 60                   return t;
 61             }
 62       }
 63       level[u]=0xff;
 64       return 0;
 65 }
 66
 67 int main()
 68 {
 69       while(scanf("%d%d%d",&n,&f,&d)!=EOF)
 70       {
 71             memset(edges,0,sizeof(edges));
 72             int w;
 73             for(int i=1;i<=f;i++)
 74             {
 75                   scanf("%d",&w);
 76                   edges[0][i]=w;
 77             }
 78             // 0    1--> f,           f+1--->f+n,           f+n+1  --> f+2*n     f+2*n+1-->f+2*n+d      f+2*n+d+1;
 79             for(int i=1;i<=n;i++)
 80                   edges[f+i][f+n+i]=1;
 81             cnt=f+2*n+d+1;
 82             for(int i=1;i<=d;i++)
 83             {
 84                   scanf("%d",&w);
 85                   edges[f+2*n+i][cnt]=w;
 86             }
 87             for(int i=1;i<=n;i++)
 88             {
 89                   scanf("%s",str);
 90                   for(int j=0;j<f;j++)
 91                   {
 92                         if(str[j]==‘Y‘)
 93                         {
 94                               edges[j+1][f+i]=1;
 95                         }
 96                   }
 97             }
 98
 99             for(int i=1;i<=n;i++)
100             {
101                   scanf("%s",str);
102                   for(int j=0;j<d;j++)
103                   {
104                         if(str[j]==‘Y‘)
105                         {
106                               edges[f+n+i][f+2*n+j+1]=1;
107                         }
108                   }
109             }
110             int ans=0;
111             int t;
112             while(BFS())
113             {
114                   while(t=DFS(0,INF))
115                   {
116                         ans+=t;
117                   }
118             }
119             printf("%d\n",ans);
120       }
121       return 0;
122 }
时间: 2024-11-07 02:02:14

HDU 4292 Food 多源多汇入门题的相关文章

HDU 1233 还是畅通工程【最小生成树入门题,Kruskal算法+Prim算法】

还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 39929    Accepted Submission(s): 18144 Problem Description 某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离.省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路

HDU 1284 钱币兑换问题(完全背包:入门题)

http://acm.hdu.edu.cn/showproblem.php?pid=1284 题意: 在一个国家仅有1分,2分,3分硬币,将钱N (N<32768) 兑换成硬币有很多种兑法.请你编程序计算出共有多少种兑法. 分析:基础的完全背包问题. 本题限制条件是: 金钱总数<=N. 本题目标条件是: 求构造方法数目. 令dp[i][j]==x 表示用前i种硬币构造j 美分共有x种方法. 初始化:  dp为全0且dp[0][0]==1. 状态转移: dp[i][j] = sum( dp[i-

hdu 2993 MAX Average Problem(斜率DP入门题)

题目链接:hdu 2993 MAX Average Problem 题意: 给一个长度为 n 的序列,找出长度 >= k 的平均值最大的连续子序列. 题解: 这题是论文的原题,请参照2004集训队论文<周源--浅谈数形结合思想在信息学竞赛中的应用> 这题输入有点大,要加读入优化才能过. 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 5

HDU 2089 不要62【数位DP入门题】

不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 56193    Accepted Submission(s): 21755 Problem Description 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer).杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可

hdu 2516 取石子游戏 Fibonacci博弈 入门题

取石子游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3069    Accepted Submission(s): 1784 Problem Description 1堆石子有n个,两人轮流取.先取者第1次可以取任意多个,但不能全部取完.以后每次取的石子数不能超过上次取子数的2倍.取完者胜.先取者负输出"Second win&q

HDU 1251 裸的字典树、入门题

裸的字典树还是挺简单的. 四个基本操作建立.查找.插入.删除 建立新结点我是用的c++中 new操作.当然也可以用malloc,都方便 不过指针阿.地址阿.这其中关系什么的我貌似还不是很清楚阿. 因为刚开始我的头结点也是定义的指针.然后程序就炸了.我不清楚原因呢. 有待弄清楚. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #includ

hdu 3572 Task Schedule(多源多汇)

建图:多源多汇问题,大白书算法通过体添加超汇和超源 把每个任务和每一天都看做一个点,添加源点和汇点. 源点与每个任务之间连一条边,容量为完成该任务所需处理次数. 若第i个任务可以在Si至Ei天处理,则由该任务向这些天分别连一条边,容量为1,表示此任务每天只能被处理一次. 最后,从每一天连一条到汇点的边,容量为机器数M,表示每天可以处理M个任务. 若求出的最大流等于所有任务需要处理的次数之和,说明能完成任务:否则,不能完成任务. dinic算法 注意:初始化的时候可能把0连接的边给忘掉 #incl

hdu 2767 Proving Equivalences(强连通入门题)

1 /************************************************* 2 Proving Equivalences(hdu 2767) 3 强连通入门题 4 给个有向图,求至少加多少条边使得图是所有点都是强连通的 5 由a->b->c->a易知n个点至少要n条边,每个出度和入度都要大 6 于1.先求所有所有强连通分量,把每个强连通分量看成一个点 7 在找每个点的出度和入度,最后还差的出度和入度的最大值就是 8 答案. 9 10 ************

poj 1459 Power Network, 最大流,多源多汇

点击打开链接 多源多汇最大流,虚拟一个源点s'和一个汇点t',原来的源点.汇点向它们连边. #include<cstdiO> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<vector> using namespace std; const int maxn = 500 + 5; const int INF = 100