POJ 3422 最小费用流
来源:互联网 发布:批量删除淘宝购买订单 编辑:程序博客网 时间:2024/06/03 15:37
#include <cstdio>#include <iostream>#include <cstring>#include <queue>#include <algorithm>using namespace std;const int maxn = 1E5 + 10;const int maxm = 1E6 + 10;const int INF = 0x3f3f3f3f;struct Edge{ int to, next, cap, flow, cost;};Edge edge[maxm];int head[maxn], tol, pre[maxn], dis[maxn], n, k, m, a[55][55], ans;bool vis[maxn];void addedge(int u, int v, int cap, int cost){ edge[tol].to = v; edge[tol].cap = cap; edge[tol].cost = cost; edge[tol].flow = 0; edge[tol].next = head[u]; head[u] = tol++; edge[tol].to = u; edge[tol].cap = 0; edge[tol].cost = -cost; edge[tol].flow = 0; edge[tol].next = head[v]; head[v] = tol++;}bool spfa(int s, int t){ queue<int>q; memset(dis, INF, sizeof(dis)); memset(vis, 0, sizeof(vis)); memset(pre, -1, sizeof(pre)); dis[s] = 0; vis[s] = true; q.push(s); while (!q.empty()) { int u = q.front(); q.pop(); vis[u] = false; for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if (edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost) { dis[v] = dis[u] + edge[i].cost; pre[v] = i; if (!vis[v]) { vis[v] = true; q.push(v); } } } } return (pre[t] == -1 ? false : true);}int MinCostMaxFlow(int s, int t, int &cost){ int flow = 0; cost = 0; while (spfa(s, t)) { int Min = INF; for (int i = pre[t]; i != -1; i = pre[edge[i ^ 1].to]) Min = min(Min, edge[i].cap - edge[i].flow); for (int i = pre[t]; i != -1; i = pre[edge[i ^ 1].to]) { edge[i].flow += Min; edge[i ^ 1].flow -= Min; cost += edge[i].cost * Min; } flow += Min; } return flow;}int main(int argc, char const *argv[]){ while (~scanf("%d%d", &n, &k)) { tol = 0; memset(head, -1, sizeof(head)); for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { scanf("%d", &a[i][j]); addedge(n * i + j + 1, n * n + n * i + j + 1, 1, -a[i][j]); addedge(n * i + j + 1, n * n + n * i + j + 1, INF, 0); if (i < n - 1) addedge(n * n + n * i + j + 1, n * (i + 1) + j + 1, INF, 0); if (j < n - 1) addedge(n * n + n * i + j + 1, n * i + j + 1 + 1, INF, 0); } addedge(0, 1, k, 0); addedge(2 * n * n, 2 * n * n + 1, INF, 0); MinCostMaxFlow(0, 2 * n * n + 1, ans); printf("%d\n", -ans); } return 0;}
有一个n*n的矩阵,格子中的元素是费用,KaKa从左上角开始出发要到达右下角,但是他只能向下走或者向右走,且走过的格子赋值为0,可以走K次,问K次后KaKa能获得的最大费用是多少?要获得最大费用,所以假设当前步选择先下走,最终得到的结果可能不是最大值,但根据题意却把走过的格子赋为0了,这就影响了最终结果。所以进行拆点,把每个点拆成两个点,入度点和出度点,本点的入度点连接着本点的出度点,费用为本点格子的值的负值,容量为1(因为当前点的入度点只能由(上边点)/(左边点)的出度点连接,所以容量是1),这样使用流网络就保证了最终的结果不受一些不是最优解的中间过程的影响。而当前点的出度点连接下个点的入度点的费用为0,容量为K,因为可以走K次,所以在走过一次后,费用已经赋为0,容量就变成K-1,谁走进当前格子,对整体的费用已经没有影响了。
再建立一个源点和一个汇点,源点与1点(左上角)相连费用0,容量K,汇点与2*n*n+1点(右下角)相连费用0,容量为K
0 0
- POJ 3422 最小费用流
- 【最小费用流】POJ
- Poj 3422(最小费用流)
- poj 3422(最小费用最大流)
- POJ 3422 最小费用最大流
- POJ-3422-最大流最小费用
- POJ 2516 最小费用流
- poj 3680 最小费用流
- poj 2135 最小费用流
- poj 2195 最小费用流
- poj 2135 最小费用流
- POJ 2195 最小费用流
- POJ 2195 最小费用流
- poj 3068 最小费用流
- poj 2135 最小费用流
- poj 2135 #最小费用流
- poj 3422 Kaka's Matrix Travels 最小费用最大流
- POJ 3422 最小费用最大流 zkw或者普通版本
- System.arraycopy、Arrays.copyOf和ArrayList的toArray介绍
- 自定义ViewGroup初步
- Java IO:PipedReader和PipedWriter使用详解及源码分析
- js原型里的默认属性和方法
- Python科学计算数据可视化模块-Matplotlib
- POJ 3422 最小费用流
- IOS小技巧-快速注释插件VVDocumenter(以及升级xcode会失效的解决方法)
- Android中的windowSoftInputMode属性详解
- fastboot刷机——实际应用
- html5自带属性验证表单必填
- android GCM(消息推送)面向国内开发的话基本不用看了
- java面试基础总结
- html5表单上传控件Files筛选指定格式的文件:accept属性过滤excel文件
- 工资问题,关于调用文件问题