输入一个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路径覆盖)的更多相关文章

  1. 网络费用流-最小k路径覆盖

    多校联赛第一场(hdu4862) Jump Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  2. hdu 4862 KM算法 最小K路径覆盖的模型

    http://acm.hdu.edu.cn/showproblem.php?pid=4862 选t<=k次,t条路要经过全部的点一次而且只一次. 建图是问题: 我自己最初就把n*m 个点分别放入 ...

  3. HDU 4862 JUMP 最小费用最大流

    2014 多校的B题,由于我不怎么搞图论,当时碰到这个题目,我怎么想都没往网络流方面弄,不过网络流真的是个好东西,对于状态多变,无法用动规或者数据结构来很好表示的时候,非常有用 这个题目要求每个点一定 ...

  4. HDU 4862 Jump(更多的联合培训学校1)(最小费用最大流)

    职务地址:pid=4862">HDU4862 最小费用流做的还是太少. 建图想不出来. . . 直接引用官方题解的话吧... 最小K路径覆盖的模型.用费用流或者KM算法解决,构造二部图 ...

  5. HDU 4862 Jump 费用流

    又是一个看了题解以后还坑了一天的题…… 结果最后发现是抄代码的时候少写了一个负号. 题意: 有一个n*m的网格,其中每个格子上都有0~9的数字.现在你可以玩K次游戏. 一次游戏是这样定义的: 你可以选 ...

  6. Air Raid POJ - 1422 【有向无环图(DAG)的最小路径覆盖【最小不相交路径覆盖】 模板题】

    Consider a town where all the streets are one-way and each street leads from one intersection to ano ...

  7. P2172 [国家集训队]部落战争 二分图最小不相交路径覆盖

    二分图最小不相交路径覆盖 #include<bits/stdc++.h> using namespace std; ; ; ; ], nxt[MAXM << ], f[MAXM ...

  8. POJ Air Raid 【DAG的最小不相交路径覆盖】

    传送门:http://poj.org/problem?id=1422 Air Raid Time Limit: 1000MS   Memory Limit: 10000K Total Submissi ...

  9. [luoguP2765] 魔术球问题(最大流—最小不相交路径覆盖)

    传送门 枚举球的个数 num 如果 i < j && (i + j) 是完全平方数,那么 i -> j' 连一条边 再加一个超级源点 s,s -> i 再加一个超级汇 ...

随机推荐

  1. C#中的抽象方法和虚方法有什么区别?

    抽象方法是只有定义.没有实际方法体的函数,它只能在抽象函数中出现,并且在子类中必须重写:虚方法则有自己的函数体,已经提供了函数实现,但是允许在子类中重写或覆盖.重写的子类虚函数就是被覆盖了.

  2. JVM执行引擎总结(读《深入理解JVM》) 早期编译优化 DCE for java

    execution engine: 运行时栈current stack frame主要保存了 local variable table, operand stack, dynamic linking, ...

  3. Markdown 學習

    Markdown 格式由John Gruber 創建,是一種便於閱讀,非常簡潔直觀的純文本文件格式,可以方便地轉為html等其他格式,很適合與寫作,不需要關注排版問題 常用學習資源有: ###標題用 ...

  4. POJ 1390 Block

    Description 给你一堆块,每个块有颜色,每次可以消去相邻颜色块,并获得块大小平方的分数,求最高得分. Sol DP/记忆化搜索. \(f[i][j][k]\) 表示 \((i,j)\) 这个 ...

  5. mysql根据汉字拼音排序查询

    例如现在有一张数据表label,字段为id.name,此表的字符集设置为gb2312,以gb2312_chinese_ci整理. 设置InnoDB引擎的字符集也为简体中文,且整理为gb2312_chi ...

  6. HDU 1024 max sum plus

    A - Max Sum Plus Plus Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I6 ...

  7. poj3984

    定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, ...

  8. centos mysql 大量数据导入时1153 错误:1153 - Got a packet bigger than 'max_allowed_packet' bytes

    参考:http://stackoverflow.com/questions/93128/mysql-error-1153-got-a-packet-bigger-than-max-allowed-pa ...

  9. non

    I p(I q){r p(c((q>9?q-p(q/10):q)+'0')),q*10; }

  10. Junit 测试 Spring

    在测试类上加上@RunWith,和@ContextConfiguration @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration ...