题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2686

Yifenfei very like play a number game in the n*n Matrix. A positive integer number is put in each area of the Matrix.
Every
time yifenfei should to do is that choose a detour which frome the top left
point to the bottom right point and than back to the top left point with the
maximal values of sum integers that area of Matrix yifenfei choose. But from the
top to the bottom can only choose right and down, from the bottom to the top can
only choose left and up. And yifenfei can not pass the same area of the Matrix
except the start and end. 
 
题意描述:n*n的矩阵,每个数为正整数,要求从最左上的位置走到最右下的位置,每次只能向右或向下走一格,然后又从最右下的位置回到最左上的位置,每次只能向上或向左走一格,然后累加这两次路径上的数。注意每个格子只能走一次(除去最左上和最右下),即矩阵中的每个数只能加一次。
 
算法分析:这道题可以运用DP来做,但我的DP思维有限,还不大熟悉,刚好最近刷图论题,介绍一下用最小费用最大流算法解之。
把最左上看作源点,最右下看作汇点。从上往下走一次,再从下往上走一次,其实就等同于从上往下走两次罢了,即从源点到汇点找到两条价值最大且不相交的路径。
首先拆点建图:(i-1)*n+j->(i-1)*n+j+n*n(w为1(注意:源点和汇点为2,因为要找到两条路),cost为矩阵中这个数值);
(i-1)*n+j+n*n -> (i-1)*n+j+1(w为1,cost为0)
(i-1)*n+j+n*n -> i*n+j(w为1,cost为0)
然后用费用流求解即可。(不是题中明确说明每个数都为正吗,我dis[]函数初始化0WA了,这是为什么?)
 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#define inf 0x7fffffff
using namespace std;
const int maxn=+;
const int M = ; int n,from,to;
struct node
{
int v,flow,cost;
int next;
}edge[M*];
int head[maxn],edgenum;
int dis[maxn],pre[maxn],pid[maxn],vis[maxn];
int an[][]; void add(int u,int v,int flow,int cost)
{
edge[edgenum].v=v ;edge[edgenum].flow=flow;
edge[edgenum].cost=cost ;edge[edgenum].next=head[u];
head[u]=edgenum++; edge[edgenum].v=u ;edge[edgenum].flow=;
edge[edgenum].cost=-cost ;edge[edgenum].next=head[v];
head[v]=edgenum++;
} int spfa()
{
memset(vis,,sizeof(vis));
memset(dis,-,sizeof(dis));
queue<int> Q;
Q.push(from);
dis[from]=;
vis[from]=;
while (!Q.empty())
{
int u=Q.front() ;Q.pop();
vis[u]=;
for (int i=head[u] ;i!=- ;i=edge[i].next)
{
int v=edge[i].v;
if (edge[i].flow> && dis[v]<dis[u]+edge[i].cost)
{
dis[v]=dis[u]+edge[i].cost;
pre[v]=u;
pid[v]=i;
if (!vis[v])
{
vis[v]=;
Q.push(v);
}
}
}
}
return dis[to];
} int mincost()
{
int aug=,maxflow=;
int ans=;
int ncase=;
while ()
{
aug=inf;
int tmp=spfa();
if (tmp==) break;
for (int i=to ;i!=from ;i=pre[i])
{
if (edge[pid[i] ].flow<aug)
aug=edge[pid[i] ].flow;
}
for (int i=to ;i!=from ;i=pre[i])
{
edge[pid[i] ].flow -= aug;
edge[pid[i]^ ].flow += aug;
}
ans += tmp;
ncase++;
if (ncase==) break;
}
return ans-an[][]-an[n][n];
} int main()
{
while (scanf("%d",&n)!=EOF)
{
memset(head,-,sizeof(head));
edgenum=;
for (int i= ;i<=n ;i++)
{
for (int j= ;j<=n ;j++)
scanf("%d",&an[i][j]);
}
from=;
to=*n*n;
for (int i= ;i<=n ;i++)
{
for (int j= ;j<=n ;j++)
{
int u=(i-)*n+j;
int v=(i-)*n+j+n*n;
add(u,v,,an[i][j]);
if (j+<=n) add(v,u+,,);
if (i+<=n) add(v,i*n+j,,);
}
}
add(from,from+n*n,,an[][]);
add(n*n,to,,an[n][n]);
int sum=mincost();
printf("%d\n",sum);
}
return ;
}

hdu 2686 Matrix 最小费用最大流的更多相关文章

  1. HDU 2686 Matrix(最大费用最大流+拆点)

    题目链接:pid=2686">http://acm.hdu.edu.cn/showproblem.php?pid=2686 和POJ3422一样 删掉K把汇点与源点的容量改为2(由于有 ...

  2. hdu 4494 Teamwork 最小费用最大流

    Teamwork Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4494 ...

  3. HDU 4862 JUMP 最小费用最大流

    2014 多校的B题,由于我不怎么搞图论,当时碰到这个题目,我怎么想都没往网络流方面弄,不过网络流真的是个好东西,对于状态多变,无法用动规或者数据结构来很好表示的时候,非常有用 这个题目要求每个点一定 ...

  4. HDU 2686 Matrix(最大费用流)

    Matrix Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  5. POJ 2195 Going Home / HDU 1533(最小费用最大流模板)

    题目大意: 有一个最大是100 * 100 的网格图,上面有 s 个 房子和人,人每移动一个格子花费1的代价,求最小代价让所有的人都进入一个房子.每个房子只能进入一个人. 算法讨论: 注意是KM 和 ...

  6. hdu 2686&&hdu 3376(拆点+构图+最小费用最大流)

    Matrix Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  7. HDU 2686 Matrix 3376 Matrix Again(费用流)

    HDU 2686 Matrix 题目链接 3376 Matrix Again 题目链接 题意:这两题是一样的,仅仅是数据范围不一样,都是一个矩阵,从左上角走到右下角在从右下角走到左上角能得到最大价值 ...

  8. hdu 2686 Matrix && hdu 3367 Matrix Again (最大费用最大流)

    Matrix Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  9. UVa11082 Matrix Decompressing(最小费用最大流)

    题目大概有一个n*m的矩阵,已知各行所有数的和的前缀和和各列所有数的和的前缀和,且矩阵各个数都在1到20的范围内,求该矩阵的一个可能的情况. POJ2396的弱化版本吧..建图的关键在于: 把行.列看 ...

随机推荐

  1. Vue.js学习 Item7 -- 条件渲染与列表渲染

    v-if 在字符串模板中,如 Handlebars,我们得像这样写一个条件块: <!-- Handlebars 模板 --> {{#if ok}} <h1>Yes</h1 ...

  2. MongoDB(3):小的细节问题

    1.文档 {“greeting”:“hello,world”,“foo”: 3} 文档中的键/值对是有序的,下面的文档与上面的文档是完全不同的两个文档. {“foo”: 3 ,“greeting”:“ ...

  3. [译]Memory Reordering Caught in the Act

    原文:http://preshing.com/20120515/memory-reordering-caught-in-the-act/ 编写lock-free的C/C++程序时,在保证memory  ...

  4. appcan weixin 开发

    登录微信开放平台:https://open.weixin.qq.com/ 管理中心,创建移动应用,ps:创建应用需要审核,其中 应用包名 需与在线打包安卓时候的  自定义包名一致. 开放平台 应用申请 ...

  5. 【Windows】如何判断当前鼠标是否按下左键或右键

    在delphi中,很多窗体和控件的鼠标事件里面已经将鼠标按键状态封装好传给响应事件的函数,所以这种情况直接使用就可以,但在某些时候,我们没有这些事件可以处理时,想判断鼠标按键是否按下的状态,就需要借助 ...

  6. 数据结构学习笔记05图 (邻接矩阵 邻接表-->BFS DFS、最短路径)

    数据结构之图 图(Graph) 包含 一组顶点:通常用V (Vertex) 表示顶点集合 一组边:通常用E (Edge) 表示边的集合 边是顶点对:(v, w) ∈E ,其中v, w ∈ V 有向边& ...

  7. django-url调度器-高级篇

    我们在中级篇中学会了如何进行反向解析,但是有这样一个问题,在为 url 命名的时候,名字不能重复,否则会导致各种各样的问题.在 url 还少的时候保证不重名还是比较简单的,但是 url 多起来以后就比 ...

  8. openerp 常见问题 OpenERP为什么选择了时区后时间还是不对?(转载)

    OpenERP为什么选择了时区后时间还是不对? 原文地址:http://cn.openerp.cn/%E4%B8%BA%E4%BB%80%E4%B9%88%E9%80%89%E6%8B%A9%E4%B ...

  9. Android--ViewPager的无限轮播

    ViewPage_RadioButton实现带小圆点的无限轮播,效果还能凑合着用. 1.在ViewPage的监听里面这样处理 @Override public void onPageSelected( ...

  10. hdu 1890 Robotic Sort

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1890 如下: #include<cstdio> #include<cstdlib&g ...