题解-CF1307G Cow and Exercise
给 \(n\) 点 \(m\) 边的带权有向图,边 \(i\) 为 \((u_i,v_i,w_i)\)。\(q\) 次询问,每次给 \(x_i\),问修改一些边使整张图的边权和增加 \(x_i\) 后最短路最大值(可以把边权修改为浮点数)。
数据范围:\(2\le n\le 50\),\(1\le m\le n\cdot (n-1)\),\(1\le u_i,v_i\le n\),\(1\le w_i\le 10^6\),\(1\le q\le 10^5\),\(0\le x_i\le 10^5\)。
学网络流不能错过的经典例题啊!这题的思想真是又巧妙又易懂又实用。
我写的题解如下,貌似废话很多。。。
如下图:
如果 \(x=0\),最短路最长为 \(7\)。
如果 \(x=1\),最短路最长为 \(8\)。\((1,4,3)\to(1,4,4)\)。
如果 \(x=2\),最短路最长为 \(9\)。\((1,4,3)\to(1,4,5)\)。
如果 \(x=3\),最短路最长为 \(9.5\)。\((1,4,3)\to(1,4,5.5)\),\((1,2,4)\to(1,2,4.5)\)。
如果 \(x=4\),最短路最长为 \(10\)。\((1,4,3)\to(1,4,6)\),\((1,2,4)\to(1,2,5)\)。
\(\cdots\)
直到 \(x=\infty\),都只需要改 \((1,4,3)\) 和 \((1,2,4)\) 两条边。
因为它们是图中三条路径的必经之路。
学过的人应该可以发现:它们便是无权图上的最小割边。
要使带权图最短路最长,修改最小割边是最优的。
将经过同一个最小割边的路径归为一个路径集。
如上图中,设经过 \((1,2,4)\) 的路径集为 \(S_1\),经过 \((1,4,3)\) 的路径集为 \(S_2\)。
当 \(0\le x\le 2\) 时,只需修改 \(S_2\) 的割边 \((1,4,3)\)。
当 \(3\le x\) 时,需要修改 \(S_1\) 和 \(S_2\) 的割边,并要使两个路径集的最短路径相等。
类推一下,根据平均的思想,可以得出:
无论 \(x\) 取何值,修改最短路径长度最短的 \(k\) 个路径集,并使它们修改后相等是最优的。
假设这 \(k\) 个路径集修改后的最短路径都为 \(L\),则应有对于任何未被修改割边的路径集,最短路径长度 \(\ge L\)。否则去修改这条路径必然更优。
所以就可以让费用流算法上路了,这题建议用 \(\tt EK\),因为这东西很乖的,一次就增广一个路径集。
回想一下 \(\tt EK\) 的套路:\(\tt Spfa\) 找到最短路,然后增广。
如果让网络流的边 \(flow_i=1,cost_i=w_i\),则有:
增广 \(k\) 次后,当前的 \(flow=k\),并且当前的 \(cost\) 为 \(k\) 个路径集的最短路长度和。
所以可以把每次增广后的 \(flow\) 和 \(cost\) 扔进 \(\tt vector\) 里。
然后对于每个询问,\(Res=\min\{\frac{cost_j+x}{flow_j}\}\)。
这时有个问题:要是 \(j\) 不等于最优的 \(k\) 怎么办?
有个很神奇的结论:对于 \(j=k\) 的情况,\(\frac{cost_j+x}{flow_j}\) 最小。
根据上面的结论,如果 \(j>k\),因为把最短路径更长的路径集也考虑进来了,所以 \(\frac{cost_j+x}{flow_j}>\frac{cost_k+x}{flow_k}\)。
如果 \(j<k\),那么修改完后这 \(j\) 个路径集的最短路径会 \(>\) 剩下未被修改的 \(k-j\) 个路径集,所以也可得这结论。
时间复杂度 \(\Theta(n^4+nq)\)。
- 代码
#include <bits/stdc++.h>
using namespace std;
//Start
typedef long long ll;
typedef double db;
#define mp(a,b) make_pair(a,b)
#define x first
#define y second
#define b(a) a.begin()
#define e(a) a.end()
#define sz(a) int((a).size())
#define pb(a) push_back(a)
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;
//Data
const int N=50;
int n,m,q;
vector<pair<int,int>> fc;
//EK
int fn,s,t;
vector<int> e[N+7],to,fw,co;
void add(int u,int v,int f,int c){
e[u].pb(sz(to)),to.pb(v),fw.pb(f),co.pb(+c);
e[v].pb(sz(to)),to.pb(u),fw.pb(0),co.pb(-c);
}
int dep[N+7],p[N+7],vis[N+7];
int Bfs(){
for(int i=1;i<=fn;i++) dep[i]=inf,vis[i]=0;
queue<int> q; q.push(s),vis[s]=1,dep[s]=0;
while(sz(q)){
int u=q.front(); q.pop(),vis[u]=0;
for(int&v:e[u])if(fw[v]&&dep[to[v]]>dep[u]+co[v]){
dep[to[v]]=dep[u]+co[v],p[to[v]]=v;
if(!vis[to[v]]) vis[to[v]]=1,q.push(to[v]);
}
}
return dep[t]<inf;
}
int flow,cost;
void EK(){
while(Bfs()){
int f=inf;
for(int i=t;i!=s;i=to[p[i]^1]) f=min(f,fw[p[i]]);
flow+=f,cost+=dep[t]*f;
for(int i=t;i!=s;i=to[p[i]^1]) fw[p[i]]-=f,fw[p[i]^1]+=f;
fc.pb(mp(flow,cost));
}
}
//Main
int main(){
scanf("%d%d",&n,&m);
for(int i=1,u,v,w;i<=m;i++)
scanf("%d%d%d",&u,&v,&w),add(u,v,1,w);
s=1,t=fn=n,EK();
scanf("%d",&q);
for(int i=1,x;i<=q;i++){
scanf("%d",&x);
db res=inf;
for(auto d:fc) res=min(res,db(d.y+x)/d.x);
printf("%.10lf\n",res);
}
return 0;
}
祝大家学习愉快!
题解-CF1307G Cow and Exercise的更多相关文章
- 【题解】Cow Relays
题目大意 求在一张有\(m\)条边无向连通图中,点\(s\)到点\(t\)的经过\(k\)条边的最短路(\(1 \leq m \leq 100\),\(1 \leq k \leq 10^6\)). ...
- 【codeforces - 1307G】Cow and Exercise
目录 description solution accepted code details description 给定 n 点 m 边简单有向图,有边权. q 次询问,每次给出 xi.可以增加某些边 ...
- 树&图 记录
A - Lake Counting POJ - 2386 最最最最最基础的dfs 挂这道题为了提高AC率(糖水不等式 B - Paint it really, really dark gray Cod ...
- 「题解」:毛一琛/$cow$ $subsets$
问题 A: 毛一琛/$cow$ $subsets$ 时间限制: 1 Sec 内存限制: 512 MB 题面 题面谢绝公开. 题解 题名貌似是个大神??看起来像是签到题然后就死了. 首先$O(3^n) ...
- 题解【洛谷P2853】[USACO06DEC]牛的野餐Cow Picnic
题目描述 The cows are having a picnic! Each of Farmer John's \(K (1 ≤ K ≤ 100)\) cows is grazing in one ...
- POJ 3263 Tallest Cow 题解
题目 FJ's \(N (1 ≤ N ≤ 10,000)\) cows conveniently indexed 1..N are standing in a line. Each cow has a ...
- USACO07NOV Cow Relays G 题解
题目 For their physical fitness program, \(N (2 ≤ N ≤ 1,000,000)\) cows have decided to run a relay ra ...
- Hdoj 2717.Catch That Cow 题解
Problem Description Farmer John has been informed of the location of a fugitive cow and wants to cat ...
- BZOJ1604 & 洛谷2906:[USACO2008 OPEN]Cow Neighborhoods 奶牛的邻居——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1604 https://www.luogu.org/problemnew/show/P2906#sub ...
随机推荐
- 美团面试官问我: ZGC 的 Z 是什么意思
本文的阅读有一定的门槛,请先了解 GC 的基本只知识. 现代垃圾收集器的演进大部分都是往减少停顿方向发展. 像 CMS 就是分离出一些阶段使得应用线程可以和垃圾回收线程并发,当然还有利用回收线程的并行 ...
- centos7安装数据库 (系统包含预装环境mariadb)
查看系统是否安装了MySQL,有些没安装但是有路径,那是因为系统安装了mariadb-libs,对应的配置文件目录:/etc/my.cnf(下面就根据mariadb来安装mysql) 查看系统预装ma ...
- python之 栈与队列
忍不住想报一句粗口"卧槽"这尼玛python的数据结构也太特么方便了吧 想到当初学c语言的数据结构的时候,真的是一笔一划都要自己写出来,这python尼玛直接一个模块就ok 真的是 ...
- 磁盘构造/msdos分区(fdisk)格式化(mkfs)和挂载
分区不是必要的,分区是与系统盘分开,防止数据丢失. 磁盘使用流程:查看磁盘(fdisk -l)---分区---格式化(创建文件系统)----挂载(自动挂载) 分区表类型:msdos(一般是系统分区) ...
- Centos7升级内核后无法启动解决办法
前言 这个问题存在有一段时间了,之前做的centos7的ISO,在进行内核的升级以后就存在这个问题: 系统盘在板载sata口上是可以正常启动新内核并且能识别面板硬盘 系统盘插在面板口上新内核无法启动, ...
- springboot做邮件发送功能时报错No qualifying bean of type 'org.springframework.mail.javamail.JavaMailSender' available:的问题解决方案
1.检查application.yml中的配置是否正确 spring.mail.host=smtp.xxx.comspring.mail.username=xxx@xxx.comspring.mail ...
- C++运行时类型判断dynamic_cast和typeid
dynamic_cast dynamic_cast < Type-id > ( expression ) dynamic_cast<类型>(变量) 在运行期间检测类型转换是否安 ...
- mysql密码问题
这位老哥的: 版权声明:本文为CSDN博主「csdn-华仔」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明.原文链接:https://blog.csdn.net/ ...
- Springboot使用EasyExcel(仅限自己收藏)
pom文件依赖 <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel< ...
- 推荐系统实践 0x05 推荐数据集MovieLens及评测
推荐数据集MovieLens及评测 数据集简介 MoiveLens是GroupLens Research收集并发布的关于电影评分的数据集,规模也比较大,为了让我们的实验快速有效的进行,我们选取了发布于 ...