description

给定 n 点 m 边简单有向图,有边权。

q 次询问,每次给出 xi。可以增加某些边的边权,要求总增加量小于等于 xi,最大化点 1 到点 n 的最短路。

原题链接。

solution

可以去看看dls表演如何正确切这道题:读完题发现是原题,找题解读了一遍,过了。

设答案的下界为 \(D\),边权增长量为 \(a_{u, v}\),最短路为 \(d_i\)。

可以根据最短路的三角不等式列出如下线性规划式:

\[\min\{\sum_{(u,v)\in E}a_{u,v}\} \\
\begin{cases}
d_u - d_v+a_{u, v}\geq -w_{u,v} \\
d_n - d_1\geq D \\
d_i\geq 0, a_{u,v} \geq 0
\end{cases}
\]

如果目标函数 \(\leq x_i\),则 \(D\) 是一个合法的下界。

考虑它的对偶问题:

\[\max\{D\times f-\sum_{(u,v)\in E}w_{u,v}\times b_{u,v}\} \\
\begin{cases}
\sum_{i}b_{u,i}-\sum_{i}b_{i,u}\leq 0 & u\not=1,n \\
\sum_{i}b_{1,i}-\sum_{i}b_{i,1}-f\leq 0 \\
\sum_{i}b_{n,i}-\sum_{i}b_{i,n}+f\leq 0 \\
0\leq b_{u,v}\leq 1,0\leq f

\end{cases}
\]

注意到这个约束条件长得很像 “流量守恒” + “容量限制”。

事实上,这就是网络流的线性规划式(引用 freopen 的一句话:在一个图中,每个点入度 ≤ 出度即可构成入度 = 出度)。其中 \(1\) 为源点,\(n\) 为汇点,\(f\) 为整个网络的流量。

记 \(c = \sum w_{u,v}\times b_{u,v}\),则已知 \(f\) 时我们需要最小化 \(c\)。跑最小费用流即可。

由于 \(D\times f-c\leq x_i\),可以得到 \(D\leq\frac{x_i+c}{f}\)。

注意到二元组 \((f,c)\) 只有 \(O(n)\) 个,每次增广单位流量可以找到所有的二元组。

于是可以 \(O(n)\) 处理一次询问(也可以处理出凸包 + 二分 \(O(\log)\) 处理一次询问)。


还有另一种转化问题的方法:

一样地设下界为 \(D\),边权增长量为 \(a_i\)。考虑 1 -> n 的所有路径 \(L_p\),有线性规划式:

\[\min\{\sum_{(u,v)\in E}a_{u,v}\leq x_i\} \\
\begin{cases}
\sum_{(u,v)\in L_p}(w_{u,v}+a_{u,v})\geq D\\
a_{u,v}\geq 0
\end{cases}
\]

对偶:

\[\max\{\sum_{p}y_p\times(D - \sum_{(u,v)\in L_p} w_{u,v})\} \\
\begin{cases}
\sum y_p \leq 1 & (u, v)\in L_p \\
y_p \geq 0
\end{cases}
\]

可以看成选 \(k\) 条路径,每条边只能被一条路径经过,最小化 \(\sum_{p}y_p\times\sum_{(u,v)\in L_p} w_{u,v}\)。

这一步以后的过程就和上面的推导是一样的。

accepted code

#include <queue>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std; typedef pair<int, int> pii;
#define pr make_pair
#define fi first
#define se second namespace fgraph{
const int MAXV = 50;
const int MAXE = 10*MAXV*MAXV;
const int INF = (1 << 30); struct edge{
int to, cap, flow, cost;
edge *nxt, *rev;
}edges[MAXE + 5], *adj[MAXV + 5], *cur[MAXV + 5], *ecnt = edges;
void addedge(int u, int v, int c, int w) {
edge *p = (++ecnt), *q = (++ecnt);
(*p) = (edge){v, c, 0, w, adj[u], q}, adj[u] = p;
(*q) = (edge){u, 0, 0, -w, adj[v], p}, adj[v] = q;
}
int d[MAXV + 5], h[MAXV + 5], s, t;
bool relabel() {
for(int i=s;i<=t;i++)
h[i] += d[i], d[i] = INF, cur[i] = adj[i];
priority_queue<pii, vector<pii>, greater<pii> >que;
que.push(pr(d[t] = 0, t));
while( !que.empty() ) {
int k = que.top().fi, x = que.top().se; que.pop();
if( k != d[x] ) continue;
for(edge *p=adj[x];p;p=p->nxt) {
if( p->rev->cap > p->rev->flow ) {
int dis = k + p->rev->cost + (h[x] - h[p->to]);
if( dis < d[p->to] ) que.push(pr(d[p->to] = dis, p->to));
}
}
}
return d[s] != INF;
}
bool vis[MAXV + 5];
int aug(int x, int tot) {
if( x == t ) return tot;
vis[x] = true; int sum = 0;
for(edge *&p=cur[x];p;p=p->nxt) {
int dis = d[p->to] + p->cost + (h[p->to] - h[x]);
if( d[x] == dis && !vis[p->to] && p->cap > p->flow ) {
int del = aug(p->to, min(tot - sum, p->cap - p->flow));
sum += del, p->flow += del, p->rev->flow -= del;
if( sum == tot ) break;
}
}
vis[x] = false; return sum;
}
} int f[55];
int main() {
int n, m; scanf("%d%d", &n, &m);
for(int i=1;i<=m;i++) {
int u, v, w; scanf("%d%d%d", &u, &v, &w);
fgraph::addedge(u, v, 1, w);
}
int cnt = 0;
fgraph::s = 1, fgraph::t = n;
for(cnt = 0;fgraph::relabel();cnt++)
f[cnt + 1] = f[cnt] + fgraph::d[1] + fgraph::h[1], fgraph::aug(1, 1); int q; scanf("%d", &q);
for(int i=1;i<=q;i++) {
int x; scanf("%d", &x); double ans = 1E12;
for(int j=1;j<=cnt;j++)
ans = min(ans, 1.0*(x + f[j])/j); printf("%.9f\n", ans);
}
}

details

有如下形式的线性规划式,一般都可以对偶成费用流(据说叫作 LP 对偶费用流),如loj6511「雅礼集训 2018 Day8」B

\[\min\{\sum_{(u,v)\in E}c_{u,v}\times x_{u,v}\} \\
\begin{cases}
\phi_u - \phi_v+x_{u, v}\geq w_{u,v} \\
\phi_i\geq 0, x_{u,v} \geq 0
\end{cases}
\]

【codeforces - 1307G】Cow and Exercise的更多相关文章

  1. 【codeforces 415D】Mashmokh and ACM(普通dp)

    [codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=200 ...

  2. 【33.10%】【codeforces 604C】Alternative Thinking

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  3. 【codeforces 707E】Garlands

    [题目链接]:http://codeforces.com/contest/707/problem/E [题意] 给你一个n*m的方阵; 里面有k个联通块; 这k个联通块,每个连通块里面都是灯; 给你q ...

  4. 【codeforces 707C】Pythagorean Triples

    [题目链接]:http://codeforces.com/contest/707/problem/C [题意] 给你一个数字n; 问你这个数字是不是某个三角形的一条边; 如果是让你输出另外两条边的大小 ...

  5. 【codeforces 709D】Recover the String

    [题目链接]:http://codeforces.com/problemset/problem/709/D [题意] 给你一个序列; 给出01子列和10子列和00子列以及11子列的个数; 然后让你输出 ...

  6. 【codeforces 709B】Checkpoints

    [题目链接]:http://codeforces.com/contest/709/problem/B [题意] 让你从起点开始走过n-1个点(至少n-1个) 问你最少走多远; [题解] 肯定不多走啊; ...

  7. 【codeforces 709C】Letters Cyclic Shift

    [题目链接]:http://codeforces.com/contest/709/problem/C [题意] 让你改变一个字符串的子集(连续的一段); ->这一段的每个字符的字母都变成之前的一 ...

  8. 【Codeforces 429D】 Tricky Function

    [题目链接] http://codeforces.com/problemset/problem/429/D [算法] 令Si = A1 + A2 + ... + Ai(A的前缀和) 则g(i,j) = ...

  9. 【Codeforces 670C】 Cinema

    [题目链接] http://codeforces.com/contest/670/problem/C [算法] 离散化 [代码] #include<bits/stdc++.h> using ...

随机推荐

  1. 主动降噪,通话降噪及AI降噪之辨

    近日,三星发布的Buds Pro 耳机中,宣传有以下功能.其中涉及到噪声的,有主动降噪,通话降噪及智能降噪,很多人对他们的具体用途容易混淆,今天我们来辨析一下. 主动降噪和通话降噪完全不是一个概念,无 ...

  2. kubernetes生态--交付prometheus监控及grafana炫酷dashboard到k8s集群

    由于docker容器的特殊性,传统的zabbix无法对k8s集群内的docker状态进行监控,所以需要使用prometheus来进行监控: 什么是Prometheus? Prometheus是由Sou ...

  3. Rsyncd 同步服务

    目录 数据备份的策略 三种数据备份 三种数据备份的比较(转载) 不同数据备份类型组合说明(转载) Rsyncd 服务传输模式(remote synchronizetion deamon) 本地传输模式 ...

  4. springmvc拦截器实现登录验证

    首先创建一个实体类: Customer: 1 package com.petcare.pojo.base; 2 3 import java.sql.Date; 4 import java.sql.Ti ...

  5. 在4.0框架下使用Sqlite数据库

    在4.0框架下使用Sqlite数据库出现"混合模式程序集是针对"v2.0.50727"版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集. ...

  6. codeforces - 978D【思维】

    D. Almost Arithmetic Progression time limit per test 1 second memory limit per test 256 megabytes in ...

  7. C# LINQ (2)

    Limiting Data -- Take() and Skip() 前面讲了 筛选 和 排序,现在讲 选取皇帝选妃,层层选拔,最后留几个,让他过目,他选一个或者几个作为妃子,大概是这么个意思Take ...

  8. Leetcode(106)-从中序与后序遍历序列构造二叉树

    根据一棵树的中序遍历与后序遍历构造二叉树. 注意:你可以假设树中没有重复的元素. 例如,给出 中序遍历 inorder = [9,3,15,20,7] 后序遍历 postorder = [9,15,7 ...

  9. Media Queries语法总结

    Media Queries的语法如下所示: @media [media_query] media_type and media_feature 使用Media Queries样式模块时都必须以&quo ...

  10. Flutter CodePen challenges

    Flutter CodePen challenges 挑战赛 https://mp.weixin.qq.com/s/qIYokWN9SVgr-F7YxbJuOQ CodePen Flutter 编辑器 ...