HDU 2686 Matrix | 费用流
来源:互联网 发布:php配置环境 编辑:程序博客网 时间:2024/05/17 07:44
最大费用流
题意:
在一个矩阵中,从矩阵的左上角走到右下角,再从右下角走回左上角。
①:每个格子只能走一次。
②:去程:只能往下或者往右走;回程:只能往上或者往左走。
沿途把矩阵中的格子的值累加起来,求sum最大。
思路:
看到每个格子只能走一次。拆点!
回程去程,看起来好像顶麻烦的。把回程反过来看,其实完全可以看做是从左上角发出的一点流量。
本题是求最大费用流。可以把输入的费用数据全改成负的,算法不变,输出时改回来即可;或者修改一下bellmanFord算法里面的更新判定。
建图:
拆点:容量为1,费用根据输入。
点:分别右边,下边连一条边,容量为INF,费用为0;
源点、汇点的细节可以自己想。流量固定为两点。
(这里的建图跟我的AC代码略有一点不同)
AC代码:
#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <queue>using namespace std;#define debug cout<<"??"<<endl;const int MAXN = 2005;const int MAXEDGE = 1e5 + 5;const int INF = 0x3f3f3f3f;int n;struct CEdge{ int from, to, cap, flow, cost, next;}edge[MAXEDGE];struct CMCMF{ int s, t, pp; int head[MAXN], a[MAXN], d[MAXN], p[MAXN]; bool inq[MAXN]; CMCMF(int ss, int tt) { s = ss, t = tt; pp = 0; memset(head, -1, sizeof(head)); } void addEdge(int u, int v, int cap, int cost) { edge[pp] = (CEdge){u, v, cap, 0, cost, head[u]}; head[u] = pp++; edge[pp] = (CEdge){v, u, 0, 0, -cost, head[v]}; head[v] = pp++; } bool bellmanFord(int &flow, int &cost) { memset(d, INF, sizeof(d)); memset(inq, false, sizeof(inq)); queue <int> q; q.push(s), inq[s] = true; a[s] = INF, d[s] = 0, p[s] = -1; while(!q.empty()) { int u = q.front(); q.pop(), inq[u] = false; int next = head[u]; while(next != -1) { CEdge &e = edge[next]; if(e.cap > e.flow && d[e.to] > d[u] + e.cost) { d[e.to] = d[u] + e.cost; a[e.to] = min(a[u], e.cap - e.flow); p[e.to] = next; if(!inq[e.to]) inq[e.to] = true, q.push(e.to); } next = e.next; } } if(d[t] == INF) return false; cost += d[t] * a[t]; flow += a[t]; int u = t; while(u != s) { edge[p[u]].flow += a[t]; edge[p[u]^1].flow -= a[t]; u = edge[p[u]].from; } return true; }};int a[33][33];int main(){ while(scanf("%d",&n) != EOF) { int s = 1, t = n*n; CMCMF mcmf(s, t); int tmp; for(int i = 0;i < n; i++) { for(int j = 1;j <= n; j++) { scanf("%d",&tmp); a[i][j] = tmp; if(j != n) mcmf.addEdge(i*n+j, i*n+j+1 + n*n, 1, -tmp); if(i != n-1) mcmf.addEdge(i*n+j, (i+1)*n+j+n*n, 1, -tmp); mcmf.addEdge(i*n+j+n*n, i*n+j, 1, 0); } } //mcmf.addEdge(1+n*n, 1, 2, 0); mcmf.addEdge(n*n + n*n, n*n, 1, 0); int cost = 0, flow = 0; while(mcmf.bellmanFord(flow, cost)); //cout<<flow<<endl; cout<<-cost - a[0][1] + a[n-1][n]<<endl; } return 0;}/*31 2 310 10 103 2 1*/
0 0
- HDU 2686 Matrix | 费用流
- HDU 2686 Matrix(费用流)
- HDU 2686 Matrix 费用流
- hdu 2686 Matrix【费用流】
- HDU 2686 Matrix(费用流)
- hdu 2686 Matrix hdu 3376 Matrix Again 费用流
- HDU 2686 Matrix HDU 3376 Matrix Again 费用流
- hdu 2686 Matrix 最小费用最大流
- hdu 2686 Matrix(最大费用流)
- hdu 2686 Matrix 最大费用最大流
- hdu 2686 Matrix【最大费用流】
- HDU 2686 Matrix(最大费用流)
- Matrix (hdu 2686 最大费用最大流)
- HDU 2686 Matrix 最小费用最大流
- hdu 2686 Matrix【费用流Max_Cost_Max_flow】
- HDU 2686 Matrix 3376 Matrix Again(费用流)
- hdu 2686 Matrix / 3376 Matrix Again最大费用流
- hdu 2686/hdu 3376 Matrix Again 费用流模板
- Matlab编译和运行.cpp
- Samsung的ARM处理器iROM启动模式介绍
- 网络协议
- vs2010、vs2008快捷键大全
- 变量通过分配方式
- HDU 2686 Matrix | 费用流
- hduoj1088!【水题】
- 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead.
- ps简单实用
- 关于各种项目的SVN 版本控制忽略文件类型搜集
- JQuery Easy Ui dataGrid 数据表格
- 选择性阅读
- swift学习六天 项目实战-知乎日报之UITabelView使用
- Java的IO结构图和集合结构图