Poj 3422(最小费用流)
来源:互联网 发布:淘宝店铺 花呗 编辑:程序博客网 时间:2024/06/05 15:49
Description
On an N × N chessboard with a non-negative number in each grid, Kaka starts his matrix travels with SUM = 0. For each travel, Kaka moves one rook from the left-upper grid to the right-bottom one, taking care that the rook moves only to the right or down. Kaka adds the number to SUM in each grid the rook visited, and replaces it with zero. It is not difficult to know the maximum SUM Kaka can obtain for his first travel. Now Kaka is wondering what is the maximum SUM he can obtain after his Kth travel. Note the SUM is accumulative during the K travels.
Input
The first line contains two integers N and K (1 ≤ N ≤ 50, 0 ≤ K ≤ 10) described above. The following N lines represents the matrix. You can assume the numbers in the matrix are no more than 1000.
Output
The maximum SUM Kaka can obtain after his Kth travel.
Sample Input
3 21 2 30 2 11 4 2
Sample Output
15
Source
#include <cstdio>#include <cstring>#include <vector>#include<iostream>#include <algorithm>#include<queue>using namespace std;const int maxn = 5000 + 5; // 顶点的最大数目const int INF = 1000000000;struct Edge { int from, to, cap, flow, cost;};struct MCMF { int n, m, s, t; vector<Edge> edges; vector<int> G[maxn]; int inq[maxn]; // 是否在队列中 int d[maxn]; // Bellman-Ford,单位流量的费用 int p[maxn]; // 上一条弧 int a[maxn]; // 可改进量 void init(int n) { this->n = n; for(int i = 0; i < n; i++) G[i].clear(); edges.clear(); } void AddEdge(int from, int to, int cap, int cost) { edges.push_back((Edge){from, to, cap, 0, cost}); edges.push_back((Edge){to, from, 0, 0, -cost}); m = edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } bool BellmanFord(int s, int t, int &flow,int &cost) { for(int i = 0; i < n; i++) d[i] = INF; memset(inq, 0, sizeof(inq)); d[s] = 0; inq[s] = 1; p[s] = 0; a[s] = INF; queue<int> Q; Q.push(s); while(!Q.empty()) { int u = Q.front(); Q.pop(); inq[u] = 0; for(int i = 0; i < G[u].size(); i++) { Edge& e = edges[G[u][i]]; if(e.cap > e.flow && d[e.to] > d[u] + e.cost) { d[e.to] = d[u] + e.cost; p[e.to] = G[u][i]; a[e.to] = min(a[u], e.cap - e.flow); if(!inq[e.to]) { Q.push(e.to); inq[e.to] = 1; } } } } if(d[t] == INF) return false;//s-t不连通,失败退出 flow += a[t]; cost += d[t] * a[t]; int u = t; while(u != s) { edges[p[u]].flow += a[t]; edges[p[u]^1].flow -= a[t]; u = edges[p[u]].from; } return true; } // 需要保证初始网络中没有负权圈 int Mincost(int s, int t) { int flow = 0,cost = 0; while(BellmanFord(s, t,flow, cost)); return cost; }};MCMF g;int M[maxn][maxn];int main(){ int n,k; while(scanf("%d%d",&n,&k) != EOF){ for(int i = 0;i < n;i++){ for(int j = 0;j < n;j++){ scanf("%d",&M[i][j]); } } g.init(2*n*n+1); int sorce = 2*n*n,sink = 2*n*n-1; g.AddEdge(sorce,n*n,k,0); for(int i = 0;i < n;i++){ for(int j = 0;j < n;j++){ g.AddEdge(i*n+j,i*n+j+n*n,1,-M[i][j]); } } for(int i = 0;i < n;i++){ for(int j = 0;j < n;j++){ if(j != n-1){ g.AddEdge(i*n+j+n*n,i*n+j+1,INF,0); g.AddEdge(i*n+j+n*n,i*n+j+1+n*n,INF,0); } if(i != n-1){ g.AddEdge(i*n+j+n*n,(i+1)*n+j,INF,0); g.AddEdge(i*n+j+n*n,(i+1)*n+j+n*n,INF,0); } } } int ans = -g.Mincost(sorce,sink); if(k != 0) ans += M[0][0]; printf("%d\n",ans); } return 0;}
- Poj 3422(最小费用流)
- POJ 3422 最小费用流
- 【最小费用流】POJ
- POJ 3422 Kaka's Matrix Travels (最小费用流)
- poj 3422 Kaka's Matrix Travels(最小费用流)
- poj 3422(最小费用最大流)
- POJ 3422 最小费用最大流
- POJ-3422-最大流最小费用
- poj 2159(最小费用最大流)
- POJ 2516(最小费用最大流)
- poj 2195 (最小费用最大流)
- POJ 3680 Intervals(最小费用流)
- POJ 3680 Intervals(最小费用流)
- 最小费用流模板(POJ 2135)
- poj 2516(最小费用最大流)
- poj 3680(最小费用流)
- POJ 2516 最小费用流
- poj 3680 最小费用流
- android 摄像头切换---但在电视上测试失败
- Java程序连接MySQL数据库
- 倒置字符串
- linux 之最常用的20个命令
- DBA应该知道的RAID卡知识
- Poj 3422(最小费用流)
- 编程实现二叉树的建立,前序遍历,中序遍历和后续遍历
- 黑马程序员 异常
- 【D3.js数据可视化系列教程】--(七)SVG初探
- Never awaitUninterruptibly() on Netty Channels
- Map
- 《唐老师C++》之const引用
- 误把main()函数写成mian()函数竟然通过编译
- Hdu 1597 find the nth digit