K Subsequence

这个题目是这个人想吃东西,但是他每次吃的都是他的美味值都必须不递减,可以吃k次,问这个最大的美味值是多少。

这个是一个比较明显的费用流,建图也很好建,但是呢,这个题目卡spfa费用流,所以要用dij的费用流。

刚刚是第一种方法,第二种方法就是优化,减少很多边来优化这个复杂度。

因为每次的美味值都必须不递减,

所以比如我们给x建边,w[x]=a  后面我们建比a大的w[y]=b 如果后面有比b大的z位置就不建了x,z 之间的边,因为之后y,z会建边,x,z可以通过 xy,yz 来连接。

所以呢,这样子建边就少了很多条边,

这个之后还有一次很重要的操作,就是每一个拆点之间要建一条 流量为inf  费用 为 0 的边。

这个是为了保持图的连通性,比如k点,k点已经被用过一次了,但是k点之前有一个点还没有用,它可以通过k点与另外一个点相连,

但是k点已经用过了,就不可以再跑了,但是这样是不对的,所以为了保持这个图的连通性,保证答案的正确性,这个k点与它的拆点之间还要连一条边。

这条边容量应该是inf,因为你不能保证k点之前还有多少个点通过k点和k点之后的点连在一起。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <map>
#include <queue>
#include <vector>
#define inf 0x3f3f3f3f
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + ;
typedef long long ll;
struct edge {
int u, v, c, f, cost;
edge(int u, int v, int c, int f, int cost) :u(u), v(v), c(c), f(f), cost(cost) {}
};
vector<edge>e;
vector<int>G[maxn];
int a[maxn];//找增广路每个点的水流量
int p[maxn];//每次找增广路反向记录路径
int d[maxn];//SPFA算法的最短路
int inq[maxn];//SPFA算法是否在队列中
void init(int n) {
for (int i = ; i <= n; i++)G[i].clear();
e.clear();
}
void addedge(int u, int v, int c, int cost) {
e.push_back(edge(u, v, c, , cost));
e.push_back(edge(v, u, , , -cost));
int m = e.size();
G[u].push_back(m - );
G[v].push_back(m - );
}
bool bellman(int s, int t, int& flow, long long & cost) {
memset(d, 0xef, sizeof(d));
memset(inq, , sizeof(inq));
d[s] = ; inq[s] = ;//源点s的距离设为0,标记入队
p[s] = ; a[s] = INF;//源点流量为INF(和之前的最大流算法是一样的) queue<int>q;//Bellman算法和增广路算法同步进行,沿着最短路拓展增广路,得出的解一定是最小费用最大流
q.push(s);
while (!q.empty()) {
int u = q.front();
q.pop();
inq[u] = ;//入队列标记删除
for (int i = ; i < G[u].size(); i++) {
edge & now = e[G[u][i]];
int v = now.v;
if (now.c > now.f && d[v] < d[u] + now.cost)
//now.c > now.f表示这条路还未流满(和最大流一样)
//d[v] > d[u] + e.cost Bellman 算法中边的松弛
{
d[v] = d[u] + now.cost;//Bellman 算法边的松弛
p[v] = G[u][i];//反向记录边的编号
a[v] = min(a[u], now.c - now.f);//到达v点的水量取决于边剩余的容量和u点的水量
if (!inq[v]) { q.push(v); inq[v] = ; }//Bellman 算法入队
}
}
}
if (d[t] < )return false;//找不到增广路
flow += a[t];//最大流的值,此函数引用flow这个值,最后可以直接求出flow
cost += (long long)d[t] * (long long)a[t];//距离乘上到达汇点的流量就是费用
for (int u = t; u != s; u = e[p[u]].u)//逆向存边
{
e[p[u]].f += a[t];//正向边加上流量
e[p[u] ^ ].f -= a[t];//反向边减去流量 (和增广路算法一样)
}
return true;
}
int MincostMaxflow(int s, int t, long long & cost) {
cost = ;
int flow = ;
while (bellman(s, t, flow, cost));//由于Bellman函数用的是引用,所以只要一直调用就可以求出flow和cost
return flow;//返回最大流,cost引用可以直接返回最小费用
}
int f[maxn], dp[maxn];
int main() {
int w;
scanf("%d", &w);
while (w--) {
int n, k;
scanf("%d%d", &n, &k);
for (int i = ; i <= n; i++) scanf("%d", &f[i]);
int s1 = , s2 = * n + , t1 = * n + , t2 = * n + ;
init(t2);
addedge(s1, s2, k, ); addedge(t1, t2, k, );
for (int i = ; i <= n; i++) {
addedge(i, i + n, , f[i]);
addedge(i, i + n, inf, );
addedge(s2, i, , );
addedge(i + n, t1, , );
}
for (int i = ; i <= n; i++) {
int x = inf;
for (int j = i + ; j <= n; j++) {
if (f[i] <= f[j] && f[j] < x) addedge(i + n, j, , ), x = f[j];
}
}
ll cost = ;
MincostMaxflow(s1, t2, cost);
printf("%lld\n", cost);
}
return ;
}

费用流

补 第三场多校杭电 费用流 K Subsequence的更多相关文章

  1. 牛客第三场多校 E Sort String

    链接:https://www.nowcoder.com/acm/contest/141/E来源:牛客网 Eddy likes to play with string which is a sequen ...

  2. 牛客第三场多校 H Diff-prime Pairs

    链接:https://www.nowcoder.com/acm/contest/141/H来源:牛客网 Eddy has solved lots of problem involving calcul ...

  3. PACM Team(牛客第三场多校赛+dp+卡内存+打印路径)

    题目链接(貌似未报名的不能进去):https://www.nowcoder.com/acm/contest/141/A 题目: 题意:背包题意,并打印路径. 思路:正常背包思路,不过五维的dp很容易爆 ...

  4. hdu4862 2014多校B题/ 费用流(最优情况下用不大于K条路径覆盖)(不同的解法)

    题意: 一个数字矩阵,可以出发K次,每次可以从右边或者下面走,要求(在收益最大情况下)覆盖全图,不能则输出-1.(规则:每次跳一步的时候若格子数字相等则获得该数字的能量,每跳一步消耗距离的能量).每个 ...

  5. 2018 Multi-University Training Contest 9 杭电多校第九场 (有坑待补)

    咕咕咕了太久  多校博客直接从第三场跳到了第九场orz 见谅见谅(会补的!) 明明最后看下来是dp场 但是硬生生被我们做成了组合数专场…… 听说jls把我们用组合数做的题都用dp来了遍 这里只放了用组 ...

  6. 可持久化线段树的学习(区间第k大和查询历史版本的数据)(杭电多校赛第二场1011)

    以前我们学习了线段树可以知道,线段树的每一个节点都储存的是一段区间,所以线段树可以做简单的区间查询,更改等简单的操作. 而后面再做有些题目,就可能会碰到一种回退的操作.这里的回退是指回到未做各种操作之 ...

  7. 2018 HDU多校第三场赛后补题

    2018 HDU多校第三场赛后补题 从易到难来写吧,其中题意有些直接摘了Claris的,数据范围是就不标了. 如果需要可以去hdu题库里找.题号是6319 - 6331. L. Visual Cube ...

  8. 2018 Multi-University Training Contest 1 杭电多校第一场

    抱着可能杭电的多校1比牛客的多校1更恐怖的想法 看到三道签到题 幸福的都快哭出来了好吗 1001  Maximum Multiple(hdoj 6298) 链接:http://acm.hdu.edu. ...

  9. 2018牛客网暑假ACM多校训练赛(第三场)I Expected Size of Random Convex Hull 计算几何,凸包,其他

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round3-I.html 题目传送门 - 2018牛客多校赛第三场 I ...

随机推荐

  1. c++动态数组的优点,创建和删除

    动态数组可以有两种使用方式: 1:不能预先知道数组的大小使用动态数组 传统数组(静态数组)是需要在程序运行前,就指定大小,比如说 int i = 10; int a[i]; 这种就是不合法的. 因为函 ...

  2. AJ学IOS(31)UI之Quartz2D图形上下文栈

    AJ分享,必须精品 首先,前面博客说过.qurza2d的上下文中有绘图信息和绘图的属性. 但是他是怎么绘制到上下午中的呢? 我们画图时候一半会用这三个步骤: (1)获取上下文 (2)绘图 (3)渲染 ...

  3. 【翻译】Java Array的排名前十方法(Top 10 Methods for Java Arrays)

    这里列举了Java Array 的前十的方法.他们在stackoverflow最大投票的问题. The following are top 10 methods for Java Array. The ...

  4. XFS文件系统的备份与恢复

    永久修改主机名:hostnamectl set-hostname oldboy临时修改主机名:hostname xfsdump备份xfsdump -f 备份的文件位置 要备份的分区或者磁盘 免交互备份 ...

  5. mysql定期任务

    进来开发项目时遇到一个问题,就是每一周需要清理服务器数据库数据.现在我就来记录一下用Navicat for MySQL 来实现定时任务. 1.启动Navicat for MySQL,新建数据库连接,打 ...

  6. PHP常量:JSON_UNESCAPED_UNICODE

    函数: json_encode() - 对变量进行 JSON 编码 说明: json_encode ( mixed $value [, int $options = 0 [, int $depth = ...

  7. react: typescript system params method optimize

    import * as _ from "lodash"; import paramCache from "../common/param-cache" impo ...

  8. Java 反射调用方法 - 不跳过安全检查、跳过安全检查和普通方法性能比较测试

    java中反射提供灵活性同时,给运行效率带来了一定影响.写个代码测试一下 package com.xzlf.reflectTest; import java.lang.reflect.Method; ...

  9. VideoView--简单的设置全屏幕播放

    我说的最主要的是要在布局哪里设置一下,如: <com.example.mypalyer.fullScreen          android:id="@+id/videoView1& ...

  10. 解决linux(ubuntu18)下无法挂载ntfs磁盘,并读写挂载硬盘

    首先需要有ntfs-3g,没有的话sudo apt-get install ntfs-3g 挂载硬盘: chen@ilaptop:/$ sudo mount -o rw,remount /dev/sd ...