补 第三场多校杭电 费用流 K Subsequence
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的更多相关文章
- 牛客第三场多校 E Sort String
链接:https://www.nowcoder.com/acm/contest/141/E来源:牛客网 Eddy likes to play with string which is a sequen ...
- 牛客第三场多校 H Diff-prime Pairs
链接:https://www.nowcoder.com/acm/contest/141/H来源:牛客网 Eddy has solved lots of problem involving calcul ...
- PACM Team(牛客第三场多校赛+dp+卡内存+打印路径)
题目链接(貌似未报名的不能进去):https://www.nowcoder.com/acm/contest/141/A 题目: 题意:背包题意,并打印路径. 思路:正常背包思路,不过五维的dp很容易爆 ...
- hdu4862 2014多校B题/ 费用流(最优情况下用不大于K条路径覆盖)(不同的解法)
题意: 一个数字矩阵,可以出发K次,每次可以从右边或者下面走,要求(在收益最大情况下)覆盖全图,不能则输出-1.(规则:每次跳一步的时候若格子数字相等则获得该数字的能量,每跳一步消耗距离的能量).每个 ...
- 2018 Multi-University Training Contest 9 杭电多校第九场 (有坑待补)
咕咕咕了太久 多校博客直接从第三场跳到了第九场orz 见谅见谅(会补的!) 明明最后看下来是dp场 但是硬生生被我们做成了组合数专场…… 听说jls把我们用组合数做的题都用dp来了遍 这里只放了用组 ...
- 可持久化线段树的学习(区间第k大和查询历史版本的数据)(杭电多校赛第二场1011)
以前我们学习了线段树可以知道,线段树的每一个节点都储存的是一段区间,所以线段树可以做简单的区间查询,更改等简单的操作. 而后面再做有些题目,就可能会碰到一种回退的操作.这里的回退是指回到未做各种操作之 ...
- 2018 HDU多校第三场赛后补题
2018 HDU多校第三场赛后补题 从易到难来写吧,其中题意有些直接摘了Claris的,数据范围是就不标了. 如果需要可以去hdu题库里找.题号是6319 - 6331. L. Visual Cube ...
- 2018 Multi-University Training Contest 1 杭电多校第一场
抱着可能杭电的多校1比牛客的多校1更恐怖的想法 看到三道签到题 幸福的都快哭出来了好吗 1001 Maximum Multiple(hdoj 6298) 链接:http://acm.hdu.edu. ...
- 2018牛客网暑假ACM多校训练赛(第三场)I Expected Size of Random Convex Hull 计算几何,凸包,其他
原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round3-I.html 题目传送门 - 2018牛客多校赛第三场 I ...
随机推荐
- golang环境安装和配置
go中环境安装 前言 最近在工作中需要新配置go环境,每次都要去网上查找教程,浪费时间,那么就自己总结下. 下载安装 linuxGolang官网下载地址:https://golang.org/dl/1 ...
- tf.train.AdamOptimizer 优化器
adaptive moment estimation(自适应矩估计) tf.train.AdamOptimizer( learning_rate=0.001, beta1=0.9, beta2=0.9 ...
- Retrofit 网络访问框架简单使用
1.引入远程依赖:包括okhttp;retrofit2;retrofit的GSON解析器 compile'com.squareup.okhttp3:okhttp:3.2.0' compile'com. ...
- 修改vs默认浏览器
右键你的Html或者网页项目,选择"使用以下工具浏览" 跳出选择框,选择你想要的浏览器作为默认值即可,也可以添加你想要的浏览器.
- Hash记录字符串
Hash记录字符串模板: mod常常取1e9+7,base常常取299,,127等等等....有的题目会卡Hash,因为可能会有两个不同的Hash但却有相通的Hash值...这个时候可以用双Hash来 ...
- 4. js
1.) ~ 操作符 console.log(~-2) // 1 console.log(~-1) // 0 console.log(~0) // -1 console.log(~1) // ...
- python的历史和下载python解释器
一.python的诞生 1.Python的创始人为Guido van Rossum.1989年圣诞节期间,在阿姆斯特丹,Guido为了打发圣诞节的无趣,决心开发一个新的脚本解释程序,创造了一种C和sh ...
- [HarekazeCTF2019] web
在 buuoj 上看到的这个比赛题目,期间平台关了,就拿了 Dockerfile 本地做了,web 题目感觉还不错 encode_and_encode [100] 打开靶机,前两个页面都是 html ...
- 机器学习5- 对数几率回归+Python实现
目录 1. 对数几率回归 1.1 求解 ω 和 b 2. 对数几率回归进行垃圾邮件分类 2.1 垃圾邮件分类 2.2 模型评估 混淆举证 精度 交叉验证精度 准确率召回率 F1 度量 ROC AUC ...
- C#多线程(12):线程池
目录 线程池 ThreadPool 常用属性和方法 线程池说明和示例 线程池线程数 线程池线程数说明 不支持的线程池异步委托 任务取消功能 计时器 线程池 线程池全称为托管线程池,线程池受 .NET ...