HDOJ 4862 Jump
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,最这个图跑最小费用最大流,假设满流就是存在解,反之不存在,最小费用的相反数就是能够获得的最大能量
Jump
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 546 Accepted Submission(s): 238
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
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue> using namespace std; const int maxn=110000;
const int INF=0x3f3f3f3f; int n,m,k;
int a[20][20]; struct Edge
{
int to,next,cap,flow,cost;
}edge[maxn]; int Adj[maxn],Size,N; void init()
{
memset(Adj,-1,sizeof(Adj)); Size=0;
} void addedge(int u,int v,int cap,int cost)
{
edge[Size].to=v;
edge[Size].next=Adj[u];
edge[Size].cost=cost;
edge[Size].cap=cap;
edge[Size].flow=0;
Adj[u]=Size++;
} void Add_Edge(int u,int v,int cap,int cost)
{
addedge(u,v,cap,cost);
addedge(v,u,0,-cost);
} int dist[1000],vis[1000],pre[1000]; bool spfa(int s,int t)
{
queue<int> q;
for(int i=0;i<N;i++)
{
dist[i]=INF;vis[i]=false; pre[i]=-1;
}
dist[s]=0; vis[s]=true; q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
vis[u]=false;
for(int i=Adj[u];~i;i=edge[i].next)
{
int v=edge[i].to;
if(edge[i].cap>edge[i].flow&&
dist[v]>dist[u]+edge[i].cost)
{
dist[v]=dist[u]+edge[i].cost;
pre[v]=i;
if(!vis[v])
{
vis[v]=true;
q.push(v);
}
}
}
}
if(pre[t]==-1) return false;
return true;
} int MinCostMaxFlow(int s,int t,int& cost)
{
int flow=0;
cost=0;
while(spfa(s,t))
{
int Min=INF;
for(int i=pre[t];~i;i=pre[edge[i^1].to])
{
if(Min>edge[i].cap-edge[i].flow)
Min=edge[i].cap-edge[i].flow;
}
for(int i=pre[t];~i;i=pre[edge[i^1].to])
{
edge[i].flow+=Min;
edge[i^1].flow-=Min;
cost+=edge[i].cost*Min;
}
flow+=Min;
}
return flow;
}
char in[10010];
int main()
{
int T_T,cas=1;
scanf("%d",&T_T);
while(T_T--)
{
init();
scanf("%d%d%d",&n,&m,&k);
memset(a,0,sizeof(a));
for(int i=0;i<n;i++)
{
scanf("%s",in);
for(int j=0;j<m;j++)
{
a[i][j]=in[j]-'0';
}
}
///source:2*n*m sink:2*n*m+1 mid:2*n*m+2;
int source=2*n*m,sink=2*n*m+1,mid=2*n*m+2;
N=mid+1;
Add_Edge(source,mid,k,0);
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
int from=i*m+j;
Add_Edge(source,from,1,0);
Add_Edge(from+n*m,sink,1,0);
Add_Edge(mid,from+n*m,1,0);
for(int ii=i+1;ii<n;ii++)
{
int to=ii*m+j+n*m;
int cost=0;
if(a[i][j]==a[ii][j])
cost=a[i][j];
cost-=ii-i-1;
Add_Edge(from,to,1,-cost);
}
for(int jj=j+1;jj<m;jj++)
{
int to=i*m+jj+n*m;
int cost=0;
if(a[i][j]==a[i][jj])
cost=a[i][j];
cost-=jj-j-1;
Add_Edge(from,to,1,-cost);
}
}
}
int C,F;
F=MinCostMaxFlow(source,sink,C);
C=-C;
if(F!=n*m) C=-1;
printf("Case %d : %d\n",cas++,C);
}
return 0;
}
HDOJ 4862 Jump的更多相关文章
- HDU 4862 Jump(更多的联合培训学校1)(最小费用最大流)
职务地址:pid=4862">HDU4862 最小费用流做的还是太少. 建图想不出来. . . 直接引用官方题解的话吧... 最小K路径覆盖的模型.用费用流或者KM算法解决,构造二部图 ...
- HDU 4862 Jump(最小K路径覆盖)
输入一个n×m网格图,每个结点的值为0-9,可以从任意点出发不超过k次,走完每个点且仅访问每个结点一次,问最终的能量最大值.不可全部走完的情况输出-1. 初始能量为0. 而结点(x,y)可以跳跃到结点 ...
- HDU 4862 Jump 费用流
又是一个看了题解以后还坑了一天的题…… 结果最后发现是抄代码的时候少写了一个负号. 题意: 有一个n*m的网格,其中每个格子上都有0~9的数字.现在你可以玩K次游戏. 一次游戏是这样定义的: 你可以选 ...
- HDU 4862 Jump 任意起点最大权K链不相交覆盖
你可以从任意起点开始起跳最多K次 每次跳你可以选择往右或者往下跳 从(x1,y1)跳到(x2,y2) 消耗的能量是曼哈顿距离-1 但是如果每次跳的起点和终点格子里的数字是相同的为X的话你会得到X能量 ...
- HDU 4862 JUMP 最小费用最大流
2014 多校的B题,由于我不怎么搞图论,当时碰到这个题目,我怎么想都没往网络流方面弄,不过网络流真的是个好东西,对于状态多变,无法用动规或者数据结构来很好表示的时候,非常有用 这个题目要求每个点一定 ...
- 【HDU 2014 Multi-University Training Contest 1 1002】/【HDU 4862】Jump
多校训练就这么华丽丽的到了 ,于是乎各种华丽丽的被虐也開始了. 这是多校的1002; 最小费用最大流. 题目大意: 有n*m个方格,每一个方格都一个的十进制一位的数.你能够操作K次. 对于每一次操作, ...
- HDOJ 1009. Fat Mouse' Trade 贪心 结构体排序
FatMouse' Trade Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- HDOJ 2317. Nasty Hacks 模拟水题
Nasty Hacks Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tota ...
- HDOJ 1326. Box of Bricks 纯水题
Box of Bricks Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
随机推荐
- 搭建python集成开发环境.
需要搭建的内容一共有三项, python ,wxpython 以及spe. 其中spe 是python 的可视化集成开发环境(ide) , 其需要python GUI图形库wxpython的支 ...
- Ch03 视图基础
3.1 视图简介 3.1.1 选择待渲染视图 3.1.2 重写视图名 3.2 给视图传递数据 3.2.1 ViewDataDictionary 3.2.2 ViewBag 3.2.3 带 ...
- 用c++开发基于tcp协议的文件上传功能
用c++开发基于tcp协议的文件上传功能 2005我正在一家游戏公司做程序员,当时一直在看<Windows网络编程> 这本书,把里面提到的每种IO模型都试了一次,强烈推荐学习网络编程的同学 ...
- 基于visual Studio2013解决面试题之0908最大连续数字串
题目
- Android ble 蓝牙4.0 总结
本文介绍Android ble 蓝牙4.0,也就是说API level >= 18,且支持蓝牙4.0的手机才可以使用,如果手机系统版本API level < 18,也是用不了蓝牙4.0的哦 ...
- wince平台下使用log4net记录日志
前面我写过一篇文章是来介绍windows平台下开发软件使用log4net来记录日志的,详情请参考:用一个简单的示例说明日志记录组件log4net的使用. 我们在wince平台下开发程序也一样需要日志文 ...
- 动态面板——axure线框图部件库介绍
1.什么是Axure的动态面板 按照Axure官方网站的解释 :动态面板控件(Dynamic Panel)可以让你实现高级的交互功能,实现原型的高保真度.动态面板包含有多个状态(states),每个状 ...
- ASP.NET - 使用 Eval() 绑定数据时使用 三元运算符
ASP.NET邦定数据“<%#Eval("Sex")%>”运用三元运算符: <%#(Eval("Sex", "{0}") ...
- 全面解读WM_NOTIFY
VC中的消息的分类有3种:窗口消息.命令消息和控件通知消息,我们这里要谈的是最后一种:控件通知消息. 控件通知消息,是指这样一种消息,一个窗口内的子控件发生了一些事情,需要通知父窗口.通知消息只适用于 ...
- boost asio 异步实现tcp通讯
---恢复内容开始--- asioboost 目录(?)[-] 一前言 二实现思路 通讯包数据结构 连接对象 连接管理器 服务器端的实现 对象串行化 一.前言 boost asio可算是一个简 ...