HDU 4862 Jump(最小K路径覆盖)
输入一个n×m网格图,每个结点的值为0~9,可以从任意点出发不超过k次,走完每个点且仅访问每个结点一次,问最终的能量最大值。不可全部走完的情况输出-1.
初始能量为0。 而结点(x,y)可以跳跃到结点(x,y+dy)或(x+dx,y)。消耗能量为跳跃前后结点的曼哈顿距离 - 1 。若跳跃前后的结点的值相等,能量加上那个值。
具体建图可以参考这里http://blog.sina.com.cn/s/blog_6bddecdc0102uy9g.html
最小K路径覆盖其实在之前是见过的打过的,不过这次又不会了,说明之前不牢固。。。要认真点,没什么时间浪费了。
平时在求二分图的无权的最小覆盖的时候,用的就是 n - 最大匹配
那个从源点连流量为K,费用为0的边到的“那个结点”,实际上就上虚拟前驱。。。因为X集合其实就是Y集合的前驱。而起点的前驱就是没有前驱,即“那个结点”。
然后如果满流量的话,说明所有结点都走了一遍。
模板是找JM伙伴要的。。。据说伙伴是参考KH师兄的=。=
其实最近经常问JM题。。。感觉自己退步了=。=要加油!!!
#include<cstdio>
#include<set>
#include<cstring>
#include<iostream>
#include<stdlib.h>
#include<vector>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std; #define maxn 222
#define maxe 30000
#define inf 0x3f3f3f3f struct Edge{
int u, v, nxt, cap, cost;
}edge[maxe];
int head[maxn]; struct MinCostMaxFlow{
queue<int> que;
int add; // edges number
int vn; // total vertex number
int cost[maxn], in[maxn], pre[maxn];
bool vis[maxn];
void init(int sz){
add = ; vn = sz + ; memset(head, -, sizeof(head));
while (!que.empty()) que.pop();
}
void insert(int u, int v, int w, int c){// u, v, capacity, cost
edge[add].u = u; edge[add].v = v; edge[add].cap = w; edge[add].cost = c;
edge[add].nxt = head[u]; head[u] = add++;
edge[add].u = v; edge[add].v = u; edge[add].cap = ; edge[add].cost = -c;
edge[add].nxt = head[v]; head[v] = add++;
}
bool spfa(int s, int e){
memset(cost, 0x3f3f3f3f, sizeof(cost));
memset(in, , sizeof(in));
memset(vis, , sizeof(vis));
cost[s] = ; pre[s] = -;
que.push(s); vis[s] = true; in[s]++;
while (!que.empty()){
int u = que.front(); que.pop();
vis[u] = false;
for (int i = head[u]; i != -; i = edge[i].nxt){
int v = edge[i].v;
if (edge[i].cap > && cost[v] > cost[u] + edge[i].cost){
cost[v] = cost[u] + edge[i].cost; pre[v] = i;
if (!vis[v]){
que.push(v); vis[v] = true; in[v]++;
if (in[v] > vn) return false;
}
}
}
}
return cost[e] < inf;
}
void mincostmaxflow(int s, int e, int &mincost, int &maxflow){
mincost = , maxflow = ;
while (spfa(s, e)){
int flow = inf;
for (int i = pre[e]; i != -; i = pre[edge[i].u]){
flow = min(flow, edge[i].cap);
}
maxflow += flow;
for (int i = pre[e]; i != -; i = pre[edge[i].u]){
edge[i].cap -= flow;
edge[i ^ ].cap += flow;
}
mincost += cost[e] * flow;
}
}
}net; int nm;
char ch[][];
int main(){
int t,n,m,k,ca=;
scanf("%d",&t);
while(t--){
scanf("%d%d%d",&n,&m,&k);
nm = n*m;
for(int i=;i<n;++i)scanf("%s",ch[i]);
net.init(nm*+);
for(int i=;i<n;++i){
for(int j=;j<m;++j){
int u = i*m+j+;
for(int k=i+;k<n;++k){
int v = k*m+j+;
int tmp = -(k-i-);
if(ch[i][j]==ch[k][j]) tmp+=ch[i][j]-'';
net.insert(u,nm+v,,-tmp);
}
for(int k=j+;k<m;++k){
int v = i*m+k+;
int tmp = -(k-j-);
if(ch[i][j]==ch[i][k]) tmp+=ch[i][j]-'';
net.insert(u,nm+v,,-tmp);
}
}
}
for(int i=nm+;i<=nm*;++i) net.insert(nm*+,i,,);
for(int i=;i<=nm;++i) net.insert(,i,,);
net.insert(,nm*+,k,);
for(int i=nm+;i<=nm*;++i)net.insert(i,nm*+,,);
int cost,flow;
net.mincostmaxflow(,nm*+,cost,flow);
printf("Case %d : ",++ca);
if(flow==nm) printf("%d\n",-cost);
else puts("-1");
}
return ;
}
HDU 4862 Jump(最小K路径覆盖)的更多相关文章
- 网络费用流-最小k路径覆盖
多校联赛第一场(hdu4862) Jump Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- hdu 4862 KM算法 最小K路径覆盖的模型
http://acm.hdu.edu.cn/showproblem.php?pid=4862 选t<=k次,t条路要经过全部的点一次而且只一次. 建图是问题: 我自己最初就把n*m 个点分别放入 ...
- HDU 4862 JUMP 最小费用最大流
2014 多校的B题,由于我不怎么搞图论,当时碰到这个题目,我怎么想都没往网络流方面弄,不过网络流真的是个好东西,对于状态多变,无法用动规或者数据结构来很好表示的时候,非常有用 这个题目要求每个点一定 ...
- HDU 4862 Jump(更多的联合培训学校1)(最小费用最大流)
职务地址:pid=4862">HDU4862 最小费用流做的还是太少. 建图想不出来. . . 直接引用官方题解的话吧... 最小K路径覆盖的模型.用费用流或者KM算法解决,构造二部图 ...
- HDU 4862 Jump 费用流
又是一个看了题解以后还坑了一天的题…… 结果最后发现是抄代码的时候少写了一个负号. 题意: 有一个n*m的网格,其中每个格子上都有0~9的数字.现在你可以玩K次游戏. 一次游戏是这样定义的: 你可以选 ...
- 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 ...
- POJ Air Raid 【DAG的最小不相交路径覆盖】
传送门:http://poj.org/problem?id=1422 Air Raid Time Limit: 1000MS Memory Limit: 10000K Total Submissi ...
- [luoguP2765] 魔术球问题(最大流—最小不相交路径覆盖)
传送门 枚举球的个数 num 如果 i < j && (i + j) 是完全平方数,那么 i -> j' 连一条边 再加一个超级源点 s,s -> i 再加一个超级汇 ...
随机推荐
- nginx同一iP多域名配置方法
文章转自:http://blog.itblood.com/nginx-same-ip-multi-domain-configuration.html 下面的是我本机的配置: server { list ...
- 源码编译安装 screen
本文转自:http://blog.163.com/oracle_wwf/blog/static/213030127201211191481101/ [root@web1 soft]# wget ftp ...
- HITtrainning20140417题解
题目列表: ID Origin Title 10 / 15 Problem A FZU 2152 文件系统 0 / 16 Problem B FZU 2153 A simple geome ...
- TMS320C64X+ 中使用EDMA3中断
关于EDMA3,TI的文档有详细的介绍.园子里的文章 http://www.cnblogs.com/fpga/archive/2009/10/13/1582516.html,http://www.cn ...
- django学习<一>:安装
这两天打算摸索下和python相关的东西,然后正好小伙伴有个关于网站的任务,就怀着好奇的心态了解了下,然后就很自然地开始涉及django的问题. 首先就是django安装的问题,想不到第一步就出问题了 ...
- [译]git status
git status git status命令能展示工作目录和stage区的状态. 使用他你能看到那些修改被staged到了, 哪些没有, 哪些文件没有被Git tracked到. git statu ...
- mysql 在linux 修改账号密码
1.root用户登录到mysql数据库代码示例:/usr/local/mysql/bin/mysql -u root -p (输入密码进入mysql)2.进入mysql,输入:代码示例:use mys ...
- 问题: Oracle Database 10g 未在当前操作系统中经过认证
问题: Oracle Database 10g 未在当前操作系统中经过认证 在Windows 7中安装Oracle 10g. 使用的Orcale版本是10g. 步骤1: 在Orcale官网上下载,下载 ...
- Laravel 5.1 文档攻略 —— Eloquent Collection
简介 像all()和get(),还有一些处理模型关系这种会返回多条数据的方法,在Eloquent里面会返回一个collection对象集合(对象装在对象里),而不是像DQB的数组结果集合(对象装在数组 ...
- Unity 手指上下左右滑动的判定
using UnityEngine; using System.Collections; public class jarodInputController : MonoBehaviour { pri ...