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 再加一个超级汇 ...
随机推荐
- fedora14 安装中文输入法
We trust you have received the usual lecture (n. 演讲 讲课 讲座; 教训 训斥 告诫) from the local SystemAdministra ...
- TeX — Beauty and Fun
我是初学者,你推荐使用什么发行的 TeX? 我应该用 LaTeX 吗? 我认为最好的发行是 TeXLive CD,它不但包含了所有操作系统需要的程序,而且有许许多多宏包,如果你不是特别特殊的用户,有了 ...
- 2014 牡丹江区域赛 B D I
http://acm.zju.edu.cn/onlinejudge/showContestProblems.do?contestId=358 The 2014 ACM-ICPC Asia Mudanj ...
- hdu5009 Paint Pearls (DP+模拟链表)
http://acm.hdu.edu.cn/showproblem.php?pid=5009 2014网络赛 西安 比较难的题 Paint Pearls Time Limit: 4000/2000 M ...
- oracle 中的round()函数、null值,rownum
round()函数:四舍五入函数 传回一个数值,该数值按照指定精度进行四舍五入运算的结果. 语法:round(number[,decimals]) Number:待处理的函数 Decimals:精度, ...
- Java中Office(word/ppt/excel)转换成HTML实现
运行条件:JDK + jacob.jar + jacob.dll 1) 把jacob.dll在 JAVA_HOME\bin\ 和 JAVA_HOME\jre\bin\ 以及C:\WINDOWS\sys ...
- 利用flexbox实现按字符长度排列dom元素
说明:请使用chrome浏览器打开 See the Pen pvyjGV by lilyH (@lilyH) on CodePen. 如上图所示,我们你要实现的效果就是,(1)在一行中显示两块元素:( ...
- solr多条件查询(二)
由于现在的 需求很变态需要N多条件的叠加,本人就用了一天时间摸索加求助,终于参透出这个q和fq的强大之处. 需求如下图,有三种关系:并且.或.不含 1.如果是或者也就是改变的q的查询条件: 2.如果是 ...
- ajax访问 aspx.cs后台
--前台$.ajax({ type: "POST", contentType: "application/json", url: "WebForm2. ...
- iOS开发——网络篇——数据安全(MD5),HTTPS,检测网络状态
一.数据安全 1.提交用户的隐私数据一定要使用POST请求提交用户的隐私数据GET请求的所有参数都直接暴露在URL中请求的URL一般会记录在服务器的访问日志中服务器的访问日志是黑客攻击的重点对象之一 ...