题意:有n*m的格子,每一个格子包含一个数字,0-9。你初始的能量为0,你可以玩k次,每一个你可以选择你现在的格子的正下方或者正右方的任意一个格子跳,但必须是之前没有跳过的格子。每玩一次你都可以跳任意次。每跳一次,从(x1, y1) 到 (x2, y2),你将花费|x1-x2|+|y1-y2|-1的能量,如果起止格子的数字相同,你能获得格子里数字的能量。

问你在把每一个格子都经过的基础上,所能得到的最大能量。

每个格子只能经过一个,你可以跳少于k次。你的能量可以为负数。

>>之前做过成环覆盖所有点的题,拆点建立二分图,此题和那个题感觉有点像。

建图的方法就是源点连所有X部,流量为1,权值为0,所有Y部连汇点,流量是1,权值为0。

能够从a点走到b点,就从a的X部到b的Y部,权值就是花费。

然后在X部添加一个点Q,从源点连到Q流量为k,权值为0的边,Q到Y部每一个点都连流量为1,权值为0的边,来保证玩k次。

最后求一个最大流量最大费用就好了。

>>建图很巧妙,但是。。。不是很懂。。。。先记下方法了。。。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <bitset>
#include <cstdio>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <map>
#include <set>
#define pk(x) printf("%d\n", x)
using namespace std;
#define PI acos(-1.0)
#define EPS 1E-6
#define clr(x,c) memset(x,c,sizeof(x))
//#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll; #include <iostream>
#include <cstring>
#include <cstdio> using namespace std;
const int MAXV = ;
const int INF = <<; struct Edge { int to, cap, cost, rev; };
vector<Edge> G[MAXV];
int dist[MAXV], prv[MAXV], pre[MAXV], in[MAXV];
queue<int> que; void addedge(int from, int to, int cap, int cost) {
G[from].push_back((Edge){to, cap, cost, G[to].size()});
G[to].push_back((Edge){from, , -cost, G[from].size()-});
} int min_cost_max_flow(int s, int t, int f) {
int res = ;
while (f > ) {
for (int i = ; i <= t; ++i) dist[i] = -INF, in[i] = ;
dist[s] = ;
while (!que.empty()) que.pop();
in[s] = ;
que.push(s); while (!que.empty()) {
int u = que.front(); que.pop(); in[u] = ;
for (int i = ; i < G[u].size(); ++i) {
Edge &e = G[u][i];
if (e.cap > && dist[e.to] < dist[u] + e.cost) {
dist[e.to] = dist[u] + e.cost;
prv[e.to] = u;
pre[e.to] = i;
if (in[e.to] == ) {
in[e.to] = ;
que.push(e.to);
}
}
}
} if (dist[t] == -INF) return -; int d = f;
for (int v = t; v != s; v = prv[v]) {
d = min(d, G[prv[v]][pre[v]].cap);
}
f -= d;
res += d * dist[t];
for (int v = t; v != s; v = prv[v]) {
Edge &e = G[prv[v]][pre[v]];
e.cap -= d;
G[v][e.rev].cap += d;
}
}
return res;
} int n, m, k;
char str[][];
int id1(int x, int y) {
return x*m+y+;
}
int id2(int x, int y) {
return n*m+x*m+y+;
}
// |x1-x2|+|y1-y2|-1
int cost(int x1, int y1, int x2, int y2) {
int ans = -(abs(x1-x2)+abs(y1-y2)-);
if (str[x1][y1] == str[x2][y2]) ans += str[x1][y1] - '';
return ans;
} int main()
{
int T, cas = ;
scanf("%d", &T);
while (T--) {
scanf("%d%d%d", &n, &m, &k); for (int i = ; i < n; ++i) {
scanf("%s", str[i]);
} int src = ;
int q = n*m*+;
int sink = n*m*+; for (int i = src; i <= sink; ++i) G[i].clear(); addedge(src, q, k, ); for (int i = ; i < n; ++i) {
for (int j = ; j < m; ++j) { addedge(src, id1(i, j), , );
addedge(id2(i,j), sink, , );
addedge(q, id2(i,j), , ); for (int k = i+; k < n; ++k) {
addedge(id1(i, j), id2(k, j), , cost(i,j,k,j));
} for (int k = j+; k < m; ++k) {
addedge(id1(i,j), id2(i,k), , cost(i,j,i,k));
} }
} printf("Case %d : %d\n", ++cas, min_cost_max_flow(src, sink, n*m));
}
return ;
}

HDU4862-Jump(最大流量最大费用流)的更多相关文章

  1. HDU 4862 Jump 费用流

    又是一个看了题解以后还坑了一天的题…… 结果最后发现是抄代码的时候少写了一个负号. 题意: 有一个n*m的网格,其中每个格子上都有0~9的数字.现在你可以玩K次游戏. 一次游戏是这样定义的: 你可以选 ...

  2. hdu4862 费用流(不错)

    题意:       给你一个矩阵,你最多可以选择k条路线,k条路线的起点随意,每次行走的距离随意,但是只能往右或者下走,走过的点不能再走,而且每一步如果a->b,如果a和b的权值s相等那么就可以 ...

  3. 网络费用流-最小k路径覆盖

    多校联赛第一场(hdu4862) Jump Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  4. BZOJ3130: [Sdoi2013]费用流[最大流 实数二分]

    3130: [Sdoi2013]费用流 Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 960  Solved: 5 ...

  5. HDU4807 Lunch Time(费用流变种)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4807 Description The campus of Nanjing Universit ...

  6. BZOJ-3130 费用流 (听题目胡扯丶裸最大流) 二分判定+最大流+实数精度乱搞

    DCrusher爷喜欢A我做的水题,没办法,只能A他做不动的题了.... 3130: [Sdoi2013]费用流 Time Limit: 10 Sec Memory Limit: 128 MBSec ...

  7. 费用流&网络流模版

    费用流模版: #include<cstdio> #include<cstring> #include<queue> using namespace std; ;// ...

  8. 【BZOJ3130】费用流(最大流,二分)

    [BZOJ3130]费用流(最大流,二分) 题面 Description Alice和Bob在图论课程上学习了最大流和最小费用最大流的相关知识. 最大流问题:给定一张有向图表示运输网络,一个源点S和一 ...

  9. BZOJ2040[2009国家集训队]拯救Protoss的故乡——模拟费用流+线段树+树链剖分

    题目描述 在星历2012年,星灵英雄Zeratul预测到他所在的Aiur行星在M天后会发生持续性暴雨灾害,尤其是他们的首都.而Zeratul作为星灵族的英雄,当然是要尽自己最大的努力帮助星灵族渡过这场 ...

随机推荐

  1. highcharts 柱形堆叠图

    <!doctype html> <html lang="en"> <head> <script type="text/javas ...

  2. 手机金属外壳加工工艺:铸造、锻造、冲压、CNC

    现如今金属手机成为行业的热点,在消费电子产品中应用越来越广,本文详细介绍几种金属加工工艺及相关产品应用. 1.CNC+阳极:iPhone 5/6, HTC M7 2.锻造+CNC:华为P8,HTC M ...

  3. linux命令之-pstree使用说明

    pstree  shows running processes as a tree. The tree is rooted at either pid or init if pid is omitte ...

  4. Windows Embedded Compact 7新特性

    Windows® Embedded Compact 7是Windows Embedded CE的下一代产品,而Windows Embedded CE这款操作系统面向占用资源少的新颖设备.Windows ...

  5. Python中的函数对象与闭包

    函数在Python中是第一类对象,可以当做参数传递给其他函数,放在数据结构中,以及作为函数的返回结果. 下面的例子为接受另外一个函数作为输入并调用它 #foo.py def callf(func): ...

  6. Ruby Gem命令

    Gem是一个管理Ruby库和程序的标准包,它通过Ruby Gem(如 http://rubygems.org/ )源来查找.安装.升级和卸载软件包,非常的便捷. Ruby 1.9.2版本默认已安装Ru ...

  7. git恢复被修改的文件

    恢复到最后一次提交的改动: git checkout -- + 需要恢复的文件名 但是,需要注意的是,如果该文件已经 add 到暂存队列中,上面的命令就不灵光喽 需要先让这个文件取消暂存: git r ...

  8. hdu 1166(树状数组 或 线段树)

    线段树 (本题无需建树,少了很多) #include<cstdio> #include<cstring> int sum[5000005],rt,data,lb,rb,n,m; ...

  9. 结构体 lock_sys

    typedef struct lock_sys_struct lock_sys_t; extern lock_sys_t* lock_sys; struct lock_sys_struct{ hash ...

  10. mysql 幻读

    幻读(Phantom Read) 是指当用户读取某一范围的数据行时,B事务在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影”行.InnoDB和Falcon存储引擎通 过多版本并发 ...