网络费用流-最小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 ...
随机推荐
- android EditText设置光标、边框和图标,以及限制输入
控制边框形状,先在drawable中建一个xml文件:shape.xml <?xml version="1.0" encoding="utf-8"?> ...
- 也谈谈js的压缩,jquery压缩。【转】
问题缘由: 负责公司的开发平台研发工作,考虑的知识产权的保护工作,必须要考虑java的加密技术和js脚本的加密技术.在目前java加密很容易破解的情况下,还是先搞定js的加密和压缩,一方面可以提高页面 ...
- 从my里调出数据插入到ms2008 骨架 php
<?php $server ="XEJMZWMDIXE9CIJ";//ms,服务器IP地址,如果是本地,可以写成localhost $uid =""; / ...
- appium的inspectot使用
前提已安装好appium环境 1. 打开appium-doctor 2. 启动appium-service,点击 inspector 3. 配置手机参数,参数获取参考上篇博客 4. 点击start ...
- hibernate中一对多多对一关系设计的理解
1.单向多对一和双向多对一的区别? 只需要从一方获取另一方的数据时 就使用单向关联双方都需要获取对方数据时 就使用双向关系 部门--人员 使用人员时如果只需要获取对应部门信息(user.getdept ...
- 【转】MFC WM_CTLCOLOR 消息
WM_CTLCOLOR消息用来完成对EDIT, STATIC, BUTTON等控件设置背景和字体颜色, 其用法如下: 1.首先在自己需要设置界面的对话框上点击右键-->建立类向导-->加入 ...
- linux -- Ubuntu开启root账户,并切换到root用户登陆
启用root账户 ubuntu 的root账户具有最高的系统权限,它类似于windows系统中的管理员账号,但是比windows系统中管理员账号的权限更高,一般都情况下不要使用root账户,但是有的时 ...
- SVN版本冲突,导致出现Files 的值“ < < < < < < < .mine”无效。路径中具有非法字符。
SVN版本冲突,导致出现Files 的值“ < < < < < < < .mine”无效.路径中具有非法字符. 右键编辑.... 打开并删除含有'<&l ...
- CentOS服务器上搭建Gitlab安装步骤、中文汉化详细步骤、日常管理以及异常故障排查
一, 服务器快速搭建gitlab方法 可以参考gitlab中文社区 的教程centos7安装gitlab:https://www.gitlab.cc/downloads/#centos7centos6 ...
- XP 终端服务组件 ,SP3 多用户补丁(替换)文件
如附件 termsrv.dll 5.1.2600.5512 目前存在一个问题:每个用户只能使用一个会话.不能像2003+那样,一个用户使用多个会话. 待查找解决方案中............... ...