hdoj 3376,2686 Matrix Again 【最小费用最大流】
题意:给出一个m*n的矩阵,然后从左上角到右下角走两次,每次仅仅能向右或者向下,出了末尾点其它仅仅能走一次,不能交叉,每次走到一个格子拿走这个格子中的数字,求价值最大?
分析:非常明显费用流。開始想的到一种建图方案,可是那样的话流量全为负值的话会成一个环,所以果断换了。
建图方案是:
首先拆点,每一个点拆成两个i 和 ii ,建边,费用为当前格子的值,流量为1,初始点和末尾点为2
然后每一个点向它的右边和下边分别建边,容量为1,费用为0
s 连接 左上角 流量 2 ,费用 0
右下角连接 t 。流量为 2 。费用为 0
PS:这个题目居然卡vector,的模拟自己实现邻接表,否则的话会超内存。
ac代码:
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std; #define PB push_back
#define MP make_pair
#define Del(a,b) memset(a,b,sizeof(a)) typedef vector<int> VI;
typedef long long LL;
const LL inf = 0x3f3f3f3f;
const int N = 750000;
int cost,flow;
struct Node
{
int from,to,cap,flow,cost;
int next;
}e[N<<2];
int head[N],top;
void add_Node(int from,int to,int cap,int cost)
{
e[top] = ((Node){from,to,cap,0,cost,head[from]});
head[from] = top++;
e[top] = ((Node){to,from,0,0,-cost,head[to]});
head[to] = top++;
}
int vis[N],dis[N];
int father[N],pos[N];
bool BellManford(int s,int t,int& flow,int& cost)
{
Del(dis,inf);
Del(vis,0);
queue<int> q;
q.push(s);
vis[s]=1;
father[s]=-1;
dis[s] = 0;
pos[s] = inf;
while(!q.empty())
{
int f = q.front();
q.pop();
vis[f] = 0;
for(int i = head[f];i!=-1 ; i = e[i].next)
{
Node& tmp = e[i];
if(tmp.cap>tmp.flow && dis[tmp.to] > dis[f] + tmp.cost)
{
dis[tmp.to] = dis[f] + tmp.cost;
father[tmp.to] = i;
pos[tmp.to] = min(pos[f],tmp.cap - tmp.flow);
if(vis[tmp.to] == 0)
{
vis[tmp.to]=1;
q.push(tmp.to);
}
}
} }
if(dis[t] == inf)
return false;
flow += pos[t];
cost += dis[t]*pos[t];
for(int u = t; u!=s ; u = e[father[u]].from)
{
e[father[u]].flow += pos[t];
e[father[u]^1].flow -= pos[t];
}
return true;
}
int Mincost(int s,int t)
{
flow = 0, cost = 0;
while(BellManford(s,t,flow,cost));
return cost;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
Del(head,-1);top = 0;
int num = n*n;
int one,x;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++){
scanf("%d",&x);
if(i==0 && j==0)
one = x;
int tmp = 1;
if(i==0 && j==0 || i==n-1 && j == n-1)
tmp = 2;
add_Node(i*n+j,i*n+j+num,tmp,-x);
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if((j+1)<n)
add_Node(i*n+j+num,i*n+j+1,1,0);
if((i+1)<n)
add_Node(i*n+j+num,(i+1)*n+j,1,0);
}
}
int s = 2*num+1 , t = s + 1;
add_Node(s,0,2,0);
add_Node(num+num-1,t,2,0);
int ans = Mincost(s,t);
printf("%d\n",-ans-x-one);
}
return 0;
}
hdoj 3376,2686 Matrix Again 【最小费用最大流】的更多相关文章
- hdu 2686&&hdu 3376(拆点+构图+最小费用最大流)
Matrix Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
- hdoj 1533 Going Home 【最小费用最大流】【KM入门题】
Going Home Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tota ...
- [poj] 3422 Kaka's Matrix Travels || 最小费用最大流
原题 给一个N*N的方阵,从[1,1]到[n,n]走K次,走过每个方格加上上面的数,然后这个格上面的数变为0.求可取得的最大的值. 要求最大值,所以把边权全为负跑最小费用即可.因为只有第一次经过该点的 ...
- uva12534 Binary Matrix 2(最小费用最大流)
http://blog.csdn.net/qq564690377/article/details/17082055 做的时候觉得明显是费用流,但是真的不知道怎么建图,看了上面的博客会稍微清晰一点.后面 ...
- hdu 2686 Matrix 最小费用最大流
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2686 Yifenfei very like play a number game in the n*n ...
- hdu 2686 Matrix && hdu 3367 Matrix Again (最大费用最大流)
Matrix Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
- poj3422 Kaka's Matrix Travels(最小费用最大流问题)
/* poj3422 Kaka's Matrix Travels 不知道 k次 dp做为什么不对??? 看了大牛的代码,才知道还可以这样做! 开始没有理解将a 和 a‘ 之间建立怎样的两条边,导致程序 ...
- UVa11082 Matrix Decompressing(最小费用最大流)
题目大概有一个n*m的矩阵,已知各行所有数的和的前缀和和各列所有数的和的前缀和,且矩阵各个数都在1到20的范围内,求该矩阵的一个可能的情况. POJ2396的弱化版本吧..建图的关键在于: 把行.列看 ...
- POJ 3422 Kaka's Matrix Travels (最小费用最大流)
POJ 3422 Kaka's Matrix Travels 链接:http://poj.org/problem? id=3422 题意:有一个N*N的方格,每一个方格里面有一个数字.如今卡卡要从左上 ...
随机推荐
- Python学习————字符串相关操作
s.capitalize()-------首字母大写s.upper()------全大写s.lower()------全小写s.swapcase()---大小写翻转s.title()------每个隔 ...
- poj2411 Mondriaan's Dream (状压dp+多米诺骨牌问题)
这道题的解析这个博客写得很好 https://blog.csdn.net/shiwei408/article/details/8821853 大致意思就是我们可以只处理两行之间的关系,然后通过这两个关 ...
- java分页之假分页
假分页,顾名思义,不是真正的在数据库里进行过滤,而是从数据库查询之后,取得全部结果,在展现的时候做些手脚. import java.util.ArrayList; import java.util.L ...
- 【codeforces 757E】Bash Plays with Functions
[题目链接]:http://codeforces.com/problemset/problem/757/E [题意] 给你q个询问; 每个询问包含r和n; 让你输出f[r][n]; 这里f[0][n] ...
- Floodlight 中创建消息对象的方法
在 floodlight 中创建各种openflow message 和 action 等採用的是简单工厂方式.BasicFactory类(实现OFMessageFactory接口.) ...
- iOS KVC(Key-Value Coding)
常见用法: 获取值 valueForKey: 依据属性名取值 valueForKeyPath: 依据路径取值(如:[person valueForKeyPath:@"car.price&qu ...
- 试用友盟SDK实现Android分享微信朋友圈
社会化分享是眼下必学且火热的功能.之前有写第三方登录,那仅仅是社会化分享的一部分.今天来玩玩分享微信朋友圈. 为了方便操作,还是依照步骤写. 一,注冊 注冊应用已经在这里具体说明过了,这里就不多提了. ...
- mysql数据库连接工具类C3P0
package com.dl.network_flow.db; import java.sql.Connection; import java.sql.PreparedStatement; impor ...
- HTML5客户端数据存储机制Web Storage和Web SQL Database
引言 html5本地存储可以选择两种方式,一种是本地存储,一种是sqlite. 比如开发html5的购物车功能,就可以考虑选择其中之一,进行本地存储与操作. 又或者保存用户登录信息,可以使用local ...
- C++如何调用C#编写的 DLL
由于C#编绎出来的DLL不是计算机所能直接识别的二进制指令码,需要CLS进行再解释,说到这,我想有些朋友应该知道C#项目需要引用C++编写的DLL时,可以直接引用DLLMPORT来实现调用,而反向的话 ...