题意:

      给你一个矩阵,你最多可以选择k条路线,k条路线的起点随意,每次行走的距离随意,但是只能往右或者下走,走过的点不能再走,而且每一步如果a->b,如果a和b的权值s相等那么就可以获得s这么多能量,每一步花费的能量是|x1 - x2| + |y1 - y2| - 1,最后问你吧所有点都遍历后获得的最大能量是多少。

思路:

      每个点只能走一次,最多可以选择k条路径,要求全走完的最大,显然是费用流,我写的是最大费用最大流,(最小费用最大流也行,就是正负的问题)下面说建边。

  (1) 首先虚拟出来三个点,源点s,终点e,超级远点ss。

 *(2) 拆点 a -> a'  流量1,费用INF //每个点只能访问一次,INF是为了让所有的点都访 问到,这个是关键,如果     是最消费用流的话可以使 -INF 

  (3) ss -> s 费用0流量k  //限制路径条数

  (4) s -> a  费用0流量1  // 每一个点都可以当路径起点

  (5) a' -> b 费用 可获得价值-花费 流量是1 // 每个点让他右和下的所有点建边

  (6) a' -> e 费用0,流量1 //每个点都可以做路径终点

 *(7) s -> e  费用0,流量INF // 题目说k可以不全用,排除强制用k条导致的错误

      这样就行了,还有就是说明下这个题目如果可以覆盖的话根本不存在负的答案,题目的那句话是误导人的,如果出现负的,那么就直接是无解的,因为ans = mclow - n * m * INF,INF很大,只要有一个格子没被覆盖过,那么abs就直接是负值了。



#include<stdio.h>
#include<string.h>
#include<queue> #define N_node 220
#define N_edge 33000
#define INF 10000000

using namespace
std; typedef struct
{
int
from ,to ,next ,cost ,flow;
}
STAR; STAR E[N_edge];
int
list[N_node] ,tot;
int
s_x[N_node];
int
mer[N_edge]; void add(int a ,int b ,int c ,int d)
{

E[++tot].from = a;
E[tot].to = b;
E[tot].cost = c;
E[tot].flow = d;
E[tot].next = list[a];
list[a] = tot; E[++tot].from = b;
E[tot].to = a;
E[tot].cost = -c;
E[tot].flow = 0;
E[tot].next = list[b];
list[b] = tot;
} bool
spfa(int s ,int t ,int n)
{
for(int
i = 0 ;i <= n ;i ++)
s_x[i] = -1000000000;
int
mark[N_node] = {0};
s_x[s] = 0 ,mark[s] = 1;
queue<int>q;
q.push(s);
memset(mer ,255 ,sizeof(mer));
while(!
q.empty())
{
int
xin ,tou;
tou = q.front();
q.pop();
mark[tou] = 0;
for(int
k = list[tou] ;k ;k = E[k].next)
{

xin = E[k].to;
if(
E[k].flow && s_x[xin] < s_x[tou] + E[k].cost)
{

mer[xin] = k;
s_x[xin] = s_x[tou] + E[k].cost;
if(!
mark[xin])
{

mark[xin] = 1;
q.push(xin);
}
}
}
}
return
mer[t] != -1;
} int
M_C_Flow(int s ,int t ,int n ,int nn ,int mm)
{
int
maxcost = 0 ,minflow ,maxflow = 0;
while(
spfa(s ,t ,n))
{

maxflow = INF;
for(int
i = mer[t] ;i + 1 ;i = mer[E[i].from])
{
if(
minflow > E[i].flow)
minflow = E[i].flow;
}
for(int
i = mer[t] ;i + 1 ;i = mer[E[i].from])
{

E[i].flow -= minflow;
E[i^1].flow += minflow;
maxcost += E[i].cost * minflow;
}

maxflow += minflow;
}
return
maxcost;
} int
abss(int x)
{
return
x < 0 ? -x : x;
} int main ()
{
int
map[15][15];
int
n ,m ,k ,i ,cas = 1 ,t ,j;
scanf("%d" ,&t);
while(
t--)
{

scanf("%d %d %d" ,&n ,&m ,&k);
char
tmp[15];
for(
i = 1 ;i <= n ;i ++)
{

scanf("%s" ,tmp);
for(
j = 1 ;j <= m ;j ++)
map[i][j] = tmp[j-1] - '0';
}

memset(list ,0 ,sizeof(list)) ,tot = 1; for(i = 1 ;i <= n ;i ++)
for(
j = 1 ;j <= m ;j ++)
{
int
now = (i - 1) * m + j;
add(now ,now + n * m ,INF ,1);
} int
s = 0 ,ss = n * m * 2 + 1 ,e = n * m * 2 + 2;
add(s ,ss ,0 ,k);
for(
i = 1 ;i <= n ;i ++)
for(
j = 1 ;j <= m ;j ++)
{
int
now = (i - 1) * m + j;
add(ss ,now ,0 ,1);
add(now + n * m ,e ,0 ,1);
for(
k = i + 1 ;k <= n ;k ++)
{
int
to = (k - 1) * m + j;
int
dis = abss(i - k) - 1;
if(
map[i][j] == map[k][j])
add(now + n * m ,to ,map[i][j] - dis,1);
else
add(now + n * m ,to ,0 - dis ,1);
} for(
k = j + 1 ;k <= m ;k ++)
{
int
to = (i - 1) * m + k;
int
dis = abss(j - k) - 1;
if(
map[i][j] == map[i][k])
add(now + n * m ,to ,map[i][j] - dis,1);
else
add(now + n * m ,to ,0 - dis ,1);
}
}

add(ss ,e ,0 ,INF);
int
ans = M_C_Flow(s ,e ,e ,n ,m) - n * m * INF;
if(
ans < 0) ans = -1;
printf("Case %d : " ,cas ++);
printf("%d\n" ,ans);
}
return
0;
}

hdu4862 费用流(不错)的更多相关文章

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

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

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

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

  3. bzoj3876: [Ahoi2014&Jsoi2014]支线剧情(上下界费用流)

    传送门 一道题让我又要学可行流又要学zkw费用流…… 考虑一下,原题可以转化为一个有向图,每次走一条路径,把每一条边都至少覆盖一次,求最小代价 因为一条边每走过一次,就要付出一次代价 那不就是费用流了 ...

  4. 洛谷P3381 【模板】最小费用最大流(dijstra费用流)

    题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表 ...

  5. HDU 4862 Jump 费用流

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

  6. hdu-5988 Coding Contest(费用流)

    题目链接: Coding Contest Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 65536/65536 K (Java/Ot ...

  7. POJ2195 Going Home[费用流|二分图最大权匹配]

    Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22088   Accepted: 11155 Desc ...

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

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

  9. 洛谷 1004 dp或最大费用流

    思路: dp方法: 设dp[i][j][k][l]为两条没有交叉的路径分别走到(i,j)和(k,l)处最大价值. 则转移方程为 dp[i][j][k][l]=max(dp[i-1][j][k-1][l ...

随机推荐

  1. AndroidStudio 中 gradle.properties 的中文值获取乱码问题

    0x01 现象 在gradle.properties中定义了全局变量,然后从 build.gradle 中设置 app_name: resValue "string", " ...

  2. [译]我是如何将GTA在线模式的加载时间缩短70%的

    [译]我是如何将GTA在线模式的加载时间缩短70%的 译注: 最近在网上发现了一篇有意思的文章, 一个国外大神受不了GTA5在线模式的加载时间, 一怒之下反汇编了GTA5的源码, 并最终发现了问题的原 ...

  3. 一个 java 文件的执行过程详解

    平时我们都使用 idea.eclipse 等软件来编写代码,在编写完之后直接点击运行就可以启动程序了,那么这个过程是怎么样的? 总体过程 我们编写的 java 文件在由编译器编译后会生成对应的 cla ...

  4. POJ-3468(线段树+区间更新+区间查询)

    A Simple Problem With Integers POJ-3468 这题是区间更新的模板题,也只是区间更新和区间查询和的简单使用. 代码中需要注意的点我都已经标注出来了,容易搞混的就是up ...

  5. AJAX 加载效果(遮盖层)

    //创建遮罩层函数体 function createMask(){ var node=document.createElement('div'); node.setAttribute('id','ba ...

  6. WebRTC 音视频同步原理与实现

    所有的基于网络传输的音视频采集播放系统都会存在音视频同步的问题,作为现代互联网实时音视频通信系统的代表,WebRTC 也不例外.本文将对音视频同步的原理以及 WebRTC 的实现做深入分析. 时间戳 ...

  7. 记一次 mysql主从复制安装配置 过程

    mysql主从复制安装配置 1.centos安装及准备 去centos官网下载相应source版本的镜像文件并在vmware中安装,安装中会遇到填写installation source,输入以下即可 ...

  8. python 序列与字典

    序列概念: 序列的成员有序排列,可以通过下标访问到一个或几个元素,就类似与c语言的数组. 序列的通用的操作: 1:索引 11 = [1,2,3,4] 11[0] = 1 2:切片 11[1,2,3,4 ...

  9. [Fundamental of Power Electronics]-PART I-2.稳态变换器原理分析-2.4 Cuk变换器实例

    2.4 Cuk 变换器 作为第二个示例,考虑图2.20(a)的变换器.该变换器执行类似于降压-升压变换器的直流转换功能:它可以增加或减小直流电压的幅值,并且可以反转极性.使用晶体管和二极管的实际实现如 ...

  10. Dynamics CRM报表点击自动运行方法

    当我们点击了报表后一般会进入到条件筛选界面,再点击运行报表才可以直接运行报表.有一个方法可以点击报表后直接运行报表. 文本编辑器打开报表的rdl文件 找到如下位置的代码: 把Value部分改为: &l ...