网络费用流-最小k路径覆盖
Jump
you can choose a grid on the right or below the current grid to jump, but it has not traveled before. Every time you can jump as many times as you want, as long as you do not violate rules. If you are from (x1, y1) to (x2, y2), then you consume |x1-x2|+|y1-y2|-1
energies. Energy can be negative.
However, in a jump, if you start position and end position has same numbers S, then you can increase the energy value by S.
Give me the maximum energy you can get. Notice that you have to go each grid exactly once and you don’t have to play exactly K times.
Then T cases followed and each case begin with three numbers N, M and K. Means there are N rows and M columns, you have K times to play.
Then N lines follow, each line is a string which is made up by M numbers.
The grids only contain numbers from 0 to 9.
(T<=100, N<=10,M<=10,K<=100)
5
1 5 1
91929
1 5 2
91929
1 5 3
91929
3 3 3
333
333
333
3 3 2
333
333
333
Case 1 : 0
Case 2 : 15
Case 3 : 16
Case 4 : 18
Case 5 : -1
题目大意:给出一个n行m列的矩阵,每个坐标上都有一个权值,可以最多走k次(注意不是k步),每一次行走可以任意选择起点(必须是没有走过的点),然后可以向右或者向下走任意的步数,每一步可以跨越任意的格数,前提是满足题目的限制条件,每走一步耗费的能量是两坐标的曼哈顿距离-1,加入走的当前点的权值和前一步的权值一样,可以获得该权值的能量,问在k次行走内,走完每一格且仅走一次,最多可以获得多少能量:这道题目主要是建图,k次的建图非常巧妙。
官方题解:
最小K路径覆盖的模型,用费用流或者KM算法解决,构造二部图,X部有N*M个节点,源点向X部每个节点连一条边,流量1,费用0,Y部有N*M个节点,每个节点向汇点连一条边,流量1,费用0,如果X部的节点x可以在一步之内到达Y部的节点y,那么就连边x->y,费用为从x格子到y格子的花费能量减去得到的能量,流量1,再在X部增加一个新的节点,表示可以从任意节点出发K次,源点向其连边,费用0,流量K,这个点向Y部每个点连边,费用0,流量1,最这个图跑最小费用最大流,如果满流就是存在解,反之不存在,最小费用的相反数就是可以获得的最大能量
可以这样考虑,首先建立一个二分图,在x部内的可以到达y部的点建边<u,v>;首先求得该二部图的最小路径覆盖=节点总数-最大流;(最小路径覆盖:用最少的路径覆盖住所有的节点,且每个节点只能在一条路径上),加入k值小于最小的路径数目,那么肯定是在k次之内是不可能完成任务的。
所以这样建图之后求得是原先的最大流+k,若最大流+k<n*m则无解,输出-1,否则求出的最小费用的相反数就是最大能量。
程序;
#include"stdio.h"
#include"string.h"
#include"iostream"
#include"map"
#include"string"
#include"queue"
#include"stdlib.h"
#include"math.h"
#define M 333
#define eps 1e-10
#define inf 1000000000
#define mod 2333333
using namespace std;
struct node
{
int u,v,w,cost,next;
}edge[M*M*3];
int t,head[M],dis[M],use[M],pre[M],Max_flow,Min_cost,top[M],q[M],work[M];
void init()
{
t=0;
memset(head,-1,sizeof(head));
}
void add(int u,int v,int w,int cost)
{
edge[t].u=u;
edge[t].v=v;
edge[t].w=w;
edge[t].cost=cost;
edge[t].next=head[u];
head[u]=t++; edge[t].u=v;
edge[t].v=u;
edge[t].w=0;
edge[t].cost=-cost;
edge[t].next=head[v];
head[v]=t++;
}
int min_flow(int S,int T)
{
int ans=0;
Max_flow=0;
while(1)
{
int i;
queue<int>q;
for(i=0;i<=T+1;i++)
dis[i]=inf;
dis[S]=0;
memset(use,0,sizeof(use));
memset(pre,-1,sizeof(pre));
q.push(S);
while(!q.empty())
{
int u=q.front();
use[u]=0;
q.pop();
for(i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(edge[i].w&&dis[v]>dis[u]+edge[i].cost)
{
dis[v]=dis[u]+edge[i].cost;
pre[v]=i;
if(!use[v])
{
use[v]=1;
q.push(v);
}
}
}
}
if(dis[T]==inf)
break;
int Min=inf+1;
for(i=pre[T];i!=-1;i=pre[edge[i].u])
{
Min=min(Min,edge[i].w);
}
for(i=pre[T];i!=-1;i=pre[edge[i].u])
{
edge[i].w-=Min;
edge[i^1].w+=Min;
}
Max_flow+=Min;
ans+=Min*dis[T];
}
return ans;
}
int num[22][22],mp[22][22];
char Mp[22][22];
int main()
{
int T,kk=1;
scanf("%d",&T);
while(T--)
{
int n,m,k,i,j,r;
scanf("%d%d%d",&n,&m,&k);
int cnt=0;
init();
for(i=1;i<=n;i++)
{
scanf("%s",Mp[i]);
for(j=1;j<=m;j++)
{
mp[i][j]=Mp[i][j-1]-'0';
num[i][j]=++cnt;
}
}
for(i=1;i<=m*n;i++)
{
add(0,i,1,0);
add(i+m*n,m*n*2+1,1,0);
}
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
int Cost;
for(r=j+1;r<=m;r++)
{
if(mp[i][j]==mp[i][r])
Cost=r-j-1-mp[i][j];
else
Cost=r-j-1;
add(num[i][j],num[i][r]+m*n,1,Cost);
}
for(r=i+1;r<=n;r++)
{
if(mp[i][j]==mp[r][j])
Cost=r-i-1-mp[i][j];
else
Cost=r-i-1;
add(num[i][j],num[r][j]+m*n,1,Cost);
}
}
}
for(i=n*m+1;i<=m*n*2;i++)
add(m*n*2+2,i,1,0);
add(0,m*n*2+2,k,0);
Min_cost=min_flow(0,m*n*2+1);
printf("Case %d : ",kk++);
if(Max_flow!=n*m)
{
printf("-1\n");
continue;
}
printf("%d\n",-Min_cost);
}
}
网络费用流-最小k路径覆盖的更多相关文章
- HDU 4862 Jump(最小K路径覆盖)
输入一个n×m网格图,每个结点的值为0-9,可以从任意点出发不超过k次,走完每个点且仅访问每个结点一次,问最终的能量最大值.不可全部走完的情况输出-1. 初始能量为0. 而结点(x,y)可以跳跃到结点 ...
- [luoguP2765] 魔术球问题(最大流—最小不相交路径覆盖)
传送门 枚举球的个数 num 如果 i < j && (i + j) 是完全平方数,那么 i -> j' 连一条边 再加一个超级源点 s,s -> i 再加一个超级汇 ...
- hdu 4862 KM算法 最小K路径覆盖的模型
http://acm.hdu.edu.cn/showproblem.php?pid=4862 选t<=k次,t条路要经过全部的点一次而且只一次. 建图是问题: 我自己最初就把n*m 个点分别放入 ...
- Air Raid POJ - 1422 【有向无环图(DAG)的最小路径覆盖【最小不相交路径覆盖】 模板题】
Consider a town where all the streets are one-way and each street leads from one intersection to ano ...
- P2172 [国家集训队]部落战争 二分图最小不相交路径覆盖
二分图最小不相交路径覆盖 #include<bits/stdc++.h> using namespace std; ; ; ; ], nxt[MAXM << ], f[MAXM ...
- 【洛谷2469/BZOJ1927】[SDOI2010]星际竞速(费用流/最小路径覆盖)
题目: 洛谷2469 分析: 把题目翻译成人话:给一个带边权的DAG,求一个路径覆盖方案使路径边权总和最小.从点\(i\)开始的路径需要额外加上\(A_i\)的权值. 回xian忆chang一xue下 ...
- POJ Air Raid 【DAG的最小不相交路径覆盖】
传送门:http://poj.org/problem?id=1422 Air Raid Time Limit: 1000MS Memory Limit: 10000K Total Submissi ...
- CF802C Heidi and Library hard 费用流 区间k覆盖问题
LINK:Heidi and Library 先说一下简单版本的 就是权值都为1. 一直无脑加书 然后发现会引起冲突,可以发现此时需要扔掉一本书. 扔掉的话 可以考虑扔掉哪一本是最优的 可以发现扔掉n ...
- [模板]网络最大流 & 最小费用最大流
我的作业部落有学习资料 可学的知识点 Dinic 模板 #define rg register #define _ 10001 #define INF 2147483647 #define min(x ...
随机推荐
- Error -27740: WSA_IO_pending
Error -27740: WSA_IO_pendingAction.c(198): Error -27791: Server **** has shut down the connection pr ...
- AOP——引言
转自:http://wayfarer.cnblogs.com/articles/241012.html 1.引言 2.AOP技术基础3.Java平台AOP技术研究 4..Net平台AOP技术研究 软件 ...
- 关于B/S和C/S模式
B/S注重的是 1.服务想玩游戏的时候,就出现想看电影的时候,就出现不用下载客户端太麻烦看个电影还要下载一大堆东西,不看了 2.维护升级软件不用一台一台地重新更新,百度一直在更新,但是我们感觉不到 3 ...
- AMD和RequireJS初识----优化Web应用前端(按需动态加载JS)
RequireJS是一个非常小巧的JavaScript模块载入框架,是AMD规范最好的实现者之一.最新版本的RequireJS压缩后只有14K,堪称非常轻量.它还同时可以和其他的框架协同工作,使用Re ...
- UVa 10633 - Rare Easy Problem
题目:给定一个数N.去掉末尾的数变成M.如今已知N-M,确定N. 分析:数论.简单题. 设N = 10*a + b { 当中0 ≤ b ≤ 9 }.则M = a: N - M = N - a = 9* ...
- win7笔记本电脑怎么做wifi热点
win7设置wifi热点后非常方便,可以给其他笔记本和手机之类支持无线上网的移动设备使用,接下来请看超简单的详细设置方法. 方法/步骤 1 第一步先打开“控制面板” 2 点击“网络和Internet” ...
- Linux中的SELinux详解--16
SELinux 宽容模式(permissive) 强制模式(enforcing) 关闭(disabled) 几种模式之间的转换 在CentOS6.2 中安装intel 的c++和fortran 的编 ...
- ASP工程文件(csproj)解读
https://blog.csdn.net/austin_link/article/details/40596185 C#项目中都会有一个不起眼的文件,后缀名csproj,很多人都会忽视它.其实,这个 ...
- Extjs学习笔记--(二)
1.配置实用Extjs <link href="Extjs/resources/css/ext-all.css" rel="stylesheet" /&g ...
- scala函数进阶篇
1.求值策略scala里有两种求值策略Call By Value -先对函数实参求值,在函数体中用这个求出的参数值.Call By Name -先不对函数实参求值,而是函数实参每次在函数体内被用到时都 ...