网络费用流-最小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 ...
随机推荐
- jquery json解析详解
我们先以解析上例中的comments对象的JSON数据为例,然后再小结jQuery中解析JSON数据的方法. JSON数据如下,是一个嵌套JSON: 1 {"comments":[ ...
- 关于Cocos2d-x手机上运行游戏的时候屏幕横屏改竖屏的解决方案
cocos2d-x打包的时候默认是横屏,如果要改成竖屏,步骤如下: 1.打开项目 2.打开proj.android 3.编辑AndroidManifest.xml 4. 找到这一句android:sc ...
- Android ArryaList 笔记
Arraylist相当于动态数组,可以动态的添加或者删除其中的元素. 参考链接 http://beginnersbook.com/2013/12/java-arraylist/ package com ...
- 写给大忙人的JavaSE 8 - 学习
前面有提到过lambda和函数式接口,但是JavaSE 8 除了这两个新特性之后还提供了很多有用的东西.例如Stream. 摸索了几天,终于弄明白Stream的应用了. 先推荐一篇文章:Java 8 ...
- 第三百一十五节,Django框架,CSRF跨站请求伪造
第三百一十五节,Django框架,CSRF跨站请求伪造 全局CSRF 如果要启用防止CSRF跨站请求伪造,就需要在中间件开启CSRF #中间件 MIDDLEWARE = [ 'django.midd ...
- 在DHTML中把整个文档的各个元素作为对象处理的技术是:()
在DHTML中把整个文档的各个元素作为对象处理的技术是:() A.HTML B.CSS C.DOM D.Script(脚本语言) 解答:C DOM:文档对象模型
- perl 利用管道读取压缩文件内容
perl的文件句柄不仅支持普通文件, 还支持管道,今天需要统计一个fastq文件中的序列数和碱基数,而NGS的fastq文件一般都是gzip压缩的,所以 需要读取压缩文件中的内容,代码如下: my ( ...
- vnc远程控制软件怎么用
CC是一款不错的局域网控制软件,它的轻便让人无法相信,下载过该软件的人都知道,该软件只有大小 工具/原料 我这里使用的是vnc-E4_2_9X32中文版 被控制端的安装 1 我们先来被控制电脑 ...
- 【Java面试题】8 面向对象的特征有哪些方面 ?
面向对象的编程语言有封装.继承 .抽象.多态等4个主要的特征. 1封装: 封装是保证软件部件具有优良的模块性的基础,封装的目标就是要实现软件部件的“高内聚.低耦合”,防止程序相互依赖性而带来的变动影响 ...
- 如果返回结构体类型变量(named return value optimisation,NRVO)
貌似这是一个非常愚蠢的问题,因为对于具有良好素质的程序员而言,在C中函数返回类型为结构体类型是不是有点不合格,干嘛不用指针做传入传出呢? 测试环境:Linux IOS 3.2.0-45-generic ...