HDU 6611 K Subsequence(Dijkstra优化费用流 模板)题解
题意:
有\(n\)个数\(a_1\cdots a_n\),现要你给出\(k\)个不相交的非降子序列,使得和最大。
思路:
费用流建图,每个点拆点,费用为\(-a[i]\),然后和源点连边,和后面非降的数连边,源点和超级源点连一条容量\(k\)的边,跑费用流。
用\(spfa\)费用流\(TLE\),这里因为不会出现负环,所以用\(Dijkstra\)优化。
代码:
/*******
dijkstra优化费用流模板
*******/
//不能有负环
#include<functional> //C++编译需要头文件
typedef pair<int, int> pii;//first保存最短距离,second保存顶点的编号
struct edge {
int to, cap, cost, rev; //终点,容量(指残量网络中的),费用,反向边编号
edge() {}
edge(int to, int _cap, int _cost, int _rev):to(to), cap(_cap), cost(_cost), rev(_rev) {}
};
int V; //顶点数
int h[maxn]; //顶点的势
int dis[maxn]; //最短距离
int prevv[maxn];//最短路中的父结点
int pree[maxn]; //最短路中的父边
vector<edge> G[maxn]; //图的邻接表
void init(int n) {
V = n;
for(int i = 0; i <= V; ++i) G[i].clear();
}
void addEdge(int from, int to, int cap, int cost){
G[from].push_back(edge(to, cap, cost, G[to].size()));
G[to].push_back(edge(from, 0, -cost, G[from].size() - 1));
}
int MCMF(int s, int t, int f, int &flow){ //f为最多能流多少
int res = 0;
for(int i = 0; i < 1 + V; i++) h[i] = 0;
while(f){
priority_queue<pii, vector<pii>, greater<pii> > q;
for(int i = 0; i < 1 + V; i++) dis[i] = INF;
dis[s] = 0; q.push(pii(0, s));
while(!q.empty()) {
pii now = q.top(); q.pop();
int v = now.second;
if(dis[v] < now.first) continue;
for(int i = 0; i < G[v].size(); ++i) {
edge &e = G[v][i];
if(e.cap > 0 && dis[e.to] > dis[v] + e.cost + h[v] - h[e.to]){
dis[e.to] = dis[v] + e.cost + h[v] - h[e.to];
prevv[e.to] = v;
pree[e.to] = i;
q.push(pii(dis[e.to], e.to));
}
}
}
if(dis[t] == INF) break;
for(int i = 0; i <= V; ++i) h[i] += dis[i];
int d = f;
for(int v = t; v != s; v = prevv[v]) d = min(d, G[prevv[v]][pree[v]].cap);
f -= d; flow += d; res += d * h[t];
for(int v = t; v != s; v = prevv[v]) {
edge &e = G[prevv[v]][pree[v]];
e.cap -= d;
G[v][e.rev].cap += d;
}
}
return res;
}
#include<map>
#include<set>
#include<cmath>
#include<cstdio>
#include<stack>
#include<ctime>
#include<vector>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<iostream>
#include<algorithm>
typedef long long ll;
using namespace std;
const int maxn = 5000 + 5;
const int INF = 0x3f3f3f3f;
const ll MOD = 1e9 + 7;
using namespace std;
//不能有负环
#include<functional> //C++编译需要头文件
typedef pair<int, int> pii;//first保存最短距离,second保存顶点的编号
struct edge {
int to, cap, cost, rev; //终点,容量(指残量网络中的),费用,反向边编号
edge() {}
edge(int to, int _cap, int _cost, int _rev):to(to), cap(_cap), cost(_cost), rev(_rev) {}
};
int V; //顶点数
int h[maxn]; //顶点的势
int dis[maxn]; //最短距离
int prevv[maxn];//最短路中的父结点
int pree[maxn]; //最短路中的父边
vector<edge> G[maxn]; //图的邻接表
void init(int n) {
V = n;
for(int i = 0; i <= V; ++i) G[i].clear();
}
void addEdge(int from, int to, int cap, int cost){
G[from].push_back(edge(to, cap, cost, G[to].size()));
G[to].push_back(edge(from, 0, -cost, G[from].size() - 1));
}
int MCMF(int s, int t, int f, int &flow){ //f为最多能流多少
int res = 0;
for(int i = 0; i < 1 + V; i++) h[i] = 0;
while(f){
priority_queue<pii, vector<pii>, greater<pii> > q;
for(int i = 0; i < 1 + V; i++) dis[i] = INF;
dis[s] = 0; q.push(pii(0, s));
while(!q.empty()) {
pii now = q.top(); q.pop();
int v = now.second;
if(dis[v] < now.first) continue;
for(int i = 0; i < G[v].size(); ++i) {
edge &e = G[v][i];
if(e.cap > 0 && dis[e.to] > dis[v] + e.cost + h[v] - h[e.to]){
dis[e.to] = dis[v] + e.cost + h[v] - h[e.to];
prevv[e.to] = v;
pree[e.to] = i;
q.push(pii(dis[e.to], e.to));
}
}
}
if(dis[t] == INF) break;
for(int i = 0; i <= V; ++i) h[i] += dis[i];
int d = f;
for(int v = t; v != s; v = prevv[v]) d = min(d, G[prevv[v]][pree[v]].cap);
f -= d; flow += d; res += d * h[t];
for(int v = t; v != s; v = prevv[v]) {
edge &e = G[prevv[v]][pree[v]];
e.cap -= d;
G[v][e.rev].cap += d;
}
}
return res;
}
int a[maxn];
int main(){
int T;
scanf("%d", &T);
while(T--){
int n, k;
scanf("%d%d", &n, &k);
init(n * 2 + 5);
int s = n * 2 + 1, e = n * 2 + 2;
int ss = n * 2 + 3, se = n * 2 + 4;
for(int i = 1; i <= n; i++){
scanf("%d", &a[i]);
addEdge(i, i + n, 1, -a[i]);
addEdge(s, i, 1, 0);
addEdge(i + n, e, 1, 0);
}
for(int i = 1; i <= n; i++){
for(int j = i + 1; j <= n; j++){
if(a[i] <= a[j])
addEdge(i + n, j, 1, 0);
}
}
addEdge(ss, s, k, 0);
addEdge(e, se, k, 0);
int flow;
printf("%d\n", -MCMF(ss, se, INF, flow));
}
return 0;
}
HDU 6611 K Subsequence(Dijkstra优化费用流 模板)题解的更多相关文章
- HDU2686 费用流 模板
Matrix Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
- 洛谷P4014 分配问题【最小/大费用流】题解+AC代码
洛谷P4014 分配问题[最小/大费用流]题解+AC代码 题目描述 有 n 件工作要分配给 n 个人做.第 i 个人做第 j 件工作产生的效益为c ij. 试设计一个将 n 件工作分配给 n 个人做的 ...
- 洛谷 P4016负载平衡问题【费用流】题解+AC代码
洛谷 P4016负载平衡问题 P4014 分配问题[费用流]题解+AC代码 负载平衡问题 题目描述 GG 公司有n个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使 n ...
- Codeforces 280D k-Maximum Subsequence Sum [模拟费用流,线段树]
洛谷 Codeforces bzoj1,bzoj2 这可真是一道n倍经验题呢-- 思路 我首先想到了DP,然后矩阵,然后线段树,然后T飞-- 搜了题解之后发现是模拟费用流. 直接维护选k个子段时的最优 ...
- HDU 4780 Candy Factory(拆点费用流)
Problem Description A new candy factory opens in pku-town. The factory import M machines to produc ...
- BZOJ.3638.CF172 k-Maximum Subsequence Sum(模拟费用流 线段树)
题目链接 各种zz错误..简直了 /* 19604kb 36292ms 题意:选$k$段不相交的区间,使其权值和最大. 朴素线段树:线段树上每个点维护O(k)个信息,区间合并时O(k^2),总O(mk ...
- HDU 5988 Coding Contest(浮点数费用流)
http://acm.split.hdu.edu.cn/showproblem.php?pid=5988 题意:在acm比赛的时候有多个桌子,桌子与桌子之间都有线路相连,每个桌子上会有一些人和一些食物 ...
- 初识费用流 模板(spfa+slf优化) 餐巾计划问题
今天学习了最小费用最大流,是网络流算法之一.可以对于一个每条边有一个容量和一个费用(即每单位流的消耗)的图指定一个源点和汇点,求在从源点到汇点的流量最大的前提下的最小费用. 这里讲一种最基础也是最好掌 ...
- 【bzoj3638】Cf172 k-Maximum Subsequence Sum 模拟费用流+线段树区间合并
题目描述 给一列数,要求支持操作: 1.修改某个数的值 2.读入l,r,k,询问在[l,r]内选不相交的不超过k个子段,最大的和是多少. 输入 The first line contains inte ...
随机推荐
- Pku1236 Network of Schools
题目描述 n个学校构成一个有向图,通过m条边连接,一:问至少向图中多少个学校投放软件,可以使得所有学校直接或者间接的通过边(假设存在边(u,v),则向u投放v可以得到,而向v投放u不能通过v直接得到) ...
- 24V降压3.3V芯片,低压降线性稳压器
PW6206系列是一款高精度,高输入电压,低静态电流,高速,低压降线性稳压器具有高纹波抑制.在VOUT=5V&VIN=7V时,输入电压高达40V,负载电流高达300mA,采用BCD工艺制造.P ...
- C++ /Python 将视频中的片段转为图片
配置OpenCV :项目名称->右击->属性 VC++目录 包含目录 放 ...\build\include ...\build\include\opencv ...\build\ ...
- Linux下unix socket 读写 抓包
Linux下unix socket 读写 抓包-ubuntuer-ChinaUnix博客 http://blog.chinaunix.net/uid-9950859-id-247877.html
- (Oracle)关于blob转到目标库报ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值错误解决方案
在数据抽取时,开发需要clob类型的数据,但是目标库类型是blob类型的,于是抽取的时候报错: ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值错误 可能有以下几种原因: 可能有以下 ...
- XCTF-你是谁
前期工作 查壳,无.运行 不知道有啥用,迷宫题? 逆向分析 文件结构 查看了一下主要逻辑在background中,因为MainActivity的setContentView是background.ba ...
- tp6.0配置站点后无法访问
1.安装composer中国镜像composer config -g repo.packagist composer https://packagist.phpcomposer.com2.执行comp ...
- tp5项目部署Linux环境后无法访问解决
一.编辑fastcgi.conf文件 vim /www/server/nginx/conf/fastcgi.conf 二.添加代码 fastcgi_param PHP_ADMIN_VALUE &quo ...
- 删除Kafka中的topic
删除Kafka中的topic 一.配置delete.topic.enable=true 二.其他方法 一.配置delete.topic.enable=true 修改kafaka配置文件server.p ...
- Tomcat 详解URL请求
这里分析一个实际的请求是如何在Tomcat中被处理的,以及最后是怎么样找到要处理的Servlet的?当我们在浏览器中输入http://hostname:port/contextPath/servlet ...