hdu4292Food(最大流Dinic算法)

简介:
 /*
题意:每一个人都有喜欢的吃的和喝的,每一个人只选择一个数量的吃的和一个数量的喝的,问能满足最多的人数!?
思路:建图很是重要!f-food, p-people, d-drink
建图: 0(源点)--->f--->p---->p'---->d--->t(汇点)
将人拆分很是重要,因为每一个人最多只能有一种选择,也就是p--->p'的最大流量是 1!
如果还是不清楚,看一看下图的例子,将人拆分与不拆分的区别!

*/
1
#include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #include<vector> 6 #include<queue> 7 #define N 850 8 #define M 201000 9 #define INF 0x3f3f3f3f 10 using namespace std; 11 12 struct EDGE{ 13 int v, cap, nt; 14 }; 15 16 int first[N]; 17 EDGE g[M]; 18 int cnt; 19 int n, f, d; 20 21 void addEdge(int u, int v, int cap){ 22 g[cnt].v=v; 23 g[cnt].cap=cap; 24 g[cnt].nt=first[u]; 25 first[u]=cnt++; 26 27 g[cnt].v=u; 28 g[cnt].cap=0; 29 g[cnt].nt=first[v]; 30 first[v]=cnt++; 31 } 32 33 int ans, ss; 34 35 queue<int>q; 36 int dist[N]; 37 38 bool bfs(){ 39 memset(dist, 0, sizeof(dist)); 40 dist[0]=1; 41 q.push(0); 42 while(!q.empty()){ 43 int u=q.front(); 44 q.pop(); 45 for(int e=first[u]; ~e; e=g[e].nt){ 46 int v=g[e].v; 47 int cap=g[e].cap; 48 if(!dist[v] && cap>0){ 49 dist[v]=dist[u]+1; 50 q.push(v); 51 } 52 } 53 } 54 if(dist[ss+1]==0) return false; 55 return true; 56 } 57 58 int dfs(int u, int flow){ 59 int ff; 60 if(u==ss+1) return flow; 61 for(int e=first[u]; ~e; e=g[e].nt){ 62 int v=g[e].v; 63 int cap=g[e].cap; 64 if(dist[v]==dist[u]+1 && cap>0 && (ff=dfs(v, min(cap, flow)))){ 65 g[e].cap-=ff; 66 g[e^1].cap+=ff; 67 return ff; 68 } 69 } 70 dist[u]=-1;//表示u节点不能到达汇点! 71 return 0; 72 } 73 74 void Dinic(){ 75 ans=0; 76 int d; 77 while(bfs()) 78 while(d=dfs(0, INF)) 79 ans+=d; 80 } 81 82 int main(){ 83 while(scanf("%d%d%d", &n, &f, &d)!=EOF){ 84 ss=2*n+f+d; 85 cnt=0; 86 memset(first, -1, sizeof(first)); 87 for(int i=1; i<=f; ++i){//源点到吃的建一条有向边,最大流量为吃的的数量 88 int x; 89 scanf("%d", &x); 90 addEdge(0, i, x); 91 } 92 93 for(int i=1; i<=d; ++i){//喝的到汇点建一条有向边,最大流量为喝的的数量 94 int x; 95 scanf("%d", &x); 96 addEdge(n*2+f+i, ss+1, x); 97 } 98 for(int i=1; i<=n; ++i){//吃的到人建一条有向边,最大流量为1 99 getchar(); 100 for(int j=1; j<=f; ++j){ 101 char ch; 102 scanf("%c", &ch); 103 if(ch=='Y') 104 addEdge(j, f+i, 1); 105 } 106 } 107 108 for(int i=1; i<=n; ++i){//人到喝的建一条有向边,最大流量为1 109 addEdge(f+i, n+f+i, 1);//人属于节点容量,将人进行拆分,因为每一个人只能有一种选择! 110 getchar(); 111 for(int j=1; j<=d; ++j){ 112 char ch; 113 scanf("%c", &ch); 114 if(ch=='Y') 115 addEdge(n+f+i, f+n*2+j, 1); 116 } 117 } 118 119 Dinic(); 120 printf("%d\n", ans); 121 } 122 return 0; 123 }









本文转自 小眼儿 博客园博客,原文链接:http://www.cnblogs.com/hujunzheng/p/3950737.html,如需转载请自行联系原作者
目录
相关文章
|
6月前
|
算法
飞行员配对方案(Dinic求最大二分图匹配(对匈牙利算法的优化),以及二分图的建图方式)
飞行员配对方案(Dinic求最大二分图匹配(对匈牙利算法的优化),以及二分图的建图方式)
100 0
|
算法
计算机基础问题,最大流问题获突破性进展:新算法「快得离谱」
计算机基础问题,最大流问题获突破性进展:新算法「快得离谱」
|
机器学习/深度学习 算法
[洛谷 P3376] 网络最大流 | 模板 (Dinic算法) 入门
题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流。 输入格式 第一行包含四个正整数 n nn,m mm,s ss,t tt,分别表示点的个数、有向边的个数、源点序号、汇点序号。 接下来M行每行包含三个正整数 ui ,vi,wi ,表示第 i 条有向边从 ui 出发,到达 vi,边权为 wi即该边最大流量为 wi)。 输出格式 一行,包含一个正整数,即为该网络的最大流。
237 0
[洛谷 P3376] 网络最大流 | 模板 (Dinic算法) 入门
|
机器学习/深度学习 算法 Java
|
算法 Java
关于最大流的EdmondsKarp算法详解
最近大三学生让我去讲课,我就恶补了最大流算法,笔者认为最重要的是让学弟学妹们入门,知道算法怎么来的?为什么是这样?理解的话提出自己的改进,然后再看看Dinic、SAP和ISAP算法….. 一、概念引入       首先要先清楚最大流的含义,就是说从源点到经过的所有路径的最终到达汇点的所有流量和。
1306 0
|
算法
GraphCuts算法解析,Graphcuts算法求最大流,最小割实例
   图割论文大合集下载: http://download.csdn.net/detail/wangyaninglm/8292305   代码: /* graph.h */ /* Vladimir Kolmogorov (vnk@cs.
1204 0
|
机器学习/深度学习 算法 JavaScript
【算法导论】最大流算法
最大流问题就是在容量容许的条件下,从源点到汇点所能通过的最大流量。 1 流网络        网络流G=(v, E)是一个有向图,其中每条边(u, v)均有一个非负的容量值,记为c(u, v) ≧ 0。
1171 0
|
29天前
|
算法 安全 数据安全/隐私保护
基于game-based算法的动态频谱访问matlab仿真
本算法展示了在认知无线电网络中,通过游戏理论优化动态频谱访问,提高频谱利用率和物理层安全性。程序运行效果包括负载因子、传输功率、信噪比对用户效用和保密率的影响分析。软件版本:Matlab 2022a。完整代码包含详细中文注释和操作视频。
|
6天前
|
算法 数据安全/隐私保护 索引
OFDM系统PAPR算法的MATLAB仿真,对比SLM,PTS以及CAF,对比不同傅里叶变换长度
本项目展示了在MATLAB 2022a环境下,通过选择映射(SLM)与相位截断星座图(PTS)技术有效降低OFDM系统中PAPR的算法实现。包括无水印的算法运行效果预览、核心程序及详尽的中文注释,附带操作步骤视频,适合研究与教学使用。