网络流(最小割最大流)【POJ3308】
来源:互联网 发布:mysql的好处 编辑:程序博客网 时间:2024/04/30 16:01
【POJ3308】
题意:简单的说就是有一个方阵,告诉你方阵里的一些位置有一些敌人伞兵,而且你有一些激光枪,这些激光枪有穿透效果,也就是如果摆在第一排的排头话就可以杀死这一排的所有伞兵,当然也可以放在一列的列头可以杀死一列的伞兵。在不同行或列建立激光枪所需的费用不一样,建立这些激光枪的总费用是建立每个激光枪的乘积,求建立激光枪杀死所有伞兵的总费用。输入:第一行是测试数据T, 第二行是行数(r) 列数(c) 伞兵数(l),第三行是建立在i行的激光枪花费的费用,第四行是建立在i列所花费的费用,接着有l行是伞兵的坐标。
解题思路:该题依然是一个最小割最大流问题,首先就是建图,我们可以把伞兵视为边,行和列视为顶点,再增加一个源点和一个汇点,源点连接每个行,每个列连接汇点,容量分别为在该行和该列建立激光枪的费用,伞兵的坐标视为边,容量为无穷大!根据割的性质,源点和汇点必不连通,因此割边必定存在s->r r->c c->t中,将r->c的容量设为无穷大,则不能被选中。这样割边就在s->r c->t的集合,也就选中了对应的行和列,此时求得的最小割既为答案! 但是改题求得是乘积而不是和,那么问题来了,怎么将乘积变为和计算,那么下面直接附上代码,看完代码应该就明白了
#include<stdio.h>#include<math.h>int main(){ int x, y; while(~scanf("%d %d", &x, &y)) printf("x和y的积为log(x)+log(y)=%lf\n", (double)exp((double) log(x)+(double)log(y)));}
下面是ac代码:(值得注意的是如果用C++交的话是下面的代码, 如果用G++交的话就把最后printf里的“lf”的l去掉);
#define MAX 110#define INF 10000000#include<string.h>#include<algorithm>#include<math.h>#include<stdio.h>struct Node{ double c, f;}map[MAX][MAX];int pre[MAX]; //pre[i]为增广路径顶点i前一个顶点的序号int queue[MAX]; //数组模拟队列int s, t; //源点,汇点;bool BFS() //BFS求增广路{ int i, cur, qs, qe; //队列当前结点;队列头,队列尾 memset(pre, -1, sizeof(pre)); pre[s] = s; qs = 0; qe = 1; queue[qs] = s; while(qs < qe) { cur = queue[qs++]; for( i = 0; i <= t; i++) { if(pre[i] == -1 && map[cur][i].c-map[cur][i].f > 0) { queue[qe++] = i; pre[i] = cur; if(i == t) return 1;//汇点不在层次网络中 } } } return 0; //汇点不在层次网络中}double maxflow() //求最大流{ double max_flow = 0, min; int i; while(BFS()) { min = INF; for(i = t; i != s; i = pre[i]) //调整网络 { if( map[pre[i]][i].c - map[pre[i]][i].f < min) min = map[pre[i]][i].c - map[pre[i]][i].f; } for( i = t; i != s; i = pre[i]) { map[pre[i]][i].f += min; map[i][pre[i]].f -= min; } max_flow += min; } return max_flow; //返回最大流}int main(){ int i, n, m, l, r, cc, w; double c; scanf("%d", &w); while(w--) { memset(map, 0, sizeof(map)); scanf("%d%d%d", &n, &m, &l); s = 0; t = n+m+1; 构建网络;用对数运算将乘法转化为加法 for( i = 1; i <= n; i++) { scanf("%lf", &c); map[s][i].c = log(c); } for( i = 1; i <= m; i++) { scanf("%lf", &c); map[i+n][t].c = log(c); } for(i = 1; i <= l; i++) { scanf("%d%d", &r, &cc); map[r][n+cc].c = 10000000; } printf("%.4lf\n", exp(maxflow())); //输出时将对数值转换为原值 } return 0;}
0 0
- 网络流(最小割最大流)【POJ3308】
- poj3308 最大流最小割
- POJ3308 Paratroopers 最大流最小割
- (POJ3308)Paratroopers 最大流最小割,建图,模板题
- Poj3308 Paratroopers(最小割)
- poj3308--Paratroopers(最小割)
- POJ3308 Paratroopers(最大流)
- poj3308——Paratroopers(最小割)
- 网络流最大流最小割算法
- 网络流最大流最小割算法
- 网络流 最小割最大流定理
- 网络的最大流最小割定理
- 网络流(最小割最大流)【POJ3469】
- 网络流(最大流,最小割)基础入门详解
- 求最大网络流(最小割)总结
- 最大流/最小割
- 最大流最小割
- 最大流最小割
- Git使用大全
- 浏览器无法加载本地文件,在后台读取字节流后返回给前端显示
- 【安装教程】windows8.1 下安装ubuntu14.04 双系统
- 并发测试
- 《图说VR入门》——Unity插件DK2使用教程
- 网络流(最小割最大流)【POJ3308】
- 通过Python3.5来学习几种不同的IO模型
- S32V234专业级AVM全景+ADAS解决方案
- 如何打造一个让人愉快的框架
- MySQL_Shell_清空数据库表中的数据
- Web基础之Maven包冲突
- NTP服务及时间同步(CentOS6.x)
- android opengl es入门示例
- LeaveCriticalSection问题的解决方案