Milk Pumping G&Milk Routing S

双倍经验时间

洛谷P5837 [USACO19DEC]Milk Pumping G

洛谷P3063 [USACO12DEC]Milk Routing S

题目模型

给定\(N\)个点和\(M\)条边,对于每条边,给定连接的两个端点以及这条边的花费和“流量”

  1. 设这条路径上所有边的花费总和为\(L\)

  2. 设这条路径上所有边中“流量”值最小的为\(C\)

要求找出一条\(1\)到\(N\)的路径满足:\(L\)尽可能小的同时\(C\)尽可能大(注意是一条路径上的L和C)


解题思路

如果是单独求\(L\)或者\(C\)中的一个,那么我们很容易便能解决

但是如果要求同时维护\(L\)和\(C\)两个值,而且这两个值还是矛盾的,那我们怎么做呢?

(这里的矛盾指:\(L\)要尽量小,而同一条道路的\(C\)又要尽量大)

  • First

首先我们先来考虑用一个最短路同时维护这两个值,但经过一番思索,我们会发现无法做到

为什么?因为这两个值矛盾啊!相矛盾的两个值怎么能在同一个最短路中解决呢?

  • Second

否定了同时维护的想法,我们只能考虑分开维护,分开维护?多个最短路?

肯定也不行,为什么?维护出来的\(L\)、\(C\)分别对应的最短路径不一定是同一条啊!最短路径都不是同一条那\(L\)、\(C\)怎么会相对应呢?

  • Third

同时维护和分开维护都不行,那怎么做?

枚举

什么意思?

我们要维护对应的两个值,那我们可以枚举其中一个值,然后再在枚举的这个值的基础上去寻找对应的另一个值呀!

怎么实现呢?

假设我们枚举\(Ci\),然后跑最短路去求解对应的\(Li\),在跑最短路时判断当前点\(v\)的\(Cv\)值是否小于\(Ci\),如果小于那么就不管这个点(因为我们枚举的\(Ci\)已经是假定的最小流量值,那么所有小于\(Ci\)肯定没有用)

为什么\(Ci\)是假定的最小流量值?不是求最大的\(C\)吗?

我们不断枚举\(Ci\),找到所有对应的\(Li\),然后用一个\(ans\)来记录最终的答案,最终找到的一定是最大的\(C\)和最小的\(L\)


代码Code

#include <bits/stdc++.h>
using namespace std;
int n,m,a,b,c,f,tot,ans;
int dis[100010],vis[100010],head[100010];
priority_queue<pair<int,int> > shan; struct node {
int to,net,liu,val;
} e[100010]; inline void add(int u,int v,int w,int l) {
e[++tot].to=v;
e[tot].net=head[u];
e[tot].liu=l;
e[tot].val=w;
head[u]=tot;
} inline void dijkstra(int l) {
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[1]=0;
shan.push(make_pair(0,1));
while(!shan.empty()) {
int x=shan.top().second;
shan.pop();
if(vis[x]==1) continue;
vis[x]=1;
for(register int i=head[x];i;i=e[i].net) {
int v=e[i].to;
if(e[i].liu<l) continue;
if(dis[v]>dis[x]+e[i].val) {
dis[v]=dis[x]+e[i].val;
shan.push(make_pair(-dis[v],v));
}
}
}
} int main() {
scanf("%d%d",&n,&m);
for(register int i=1;i<=m;i++) {
scanf("%d%d%d%d",&a,&b,&c,&f);
add(a,b,c,f);
add(b,a,c,f);
}
for(register int li=1;li<=1000;li++) {
dijkstra(li);
if(dis[n]!=0x3f) ans=max(ans,li*1000000/dis[n]);
}
printf("%d",ans);
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int n,m,x,u,v,w,c,tot,ans=20050206;
int dis[510005],vis[510005],head[510005],flag[510005];
priority_queue<pair<int,int> > shan; struct node {
int to,net,val,liu;
} e[510005]; inline void add(int u,int v,int w,int l) {
e[++tot].to=v;
e[tot].val=w;
e[tot].liu=l;
e[tot].net=head[u];
head[u]=tot;
} inline void dijkstra(int li) {
for(register int i=1;i<=n;i++) {
vis[i]=0;
dis[i]=20050206;
}
dis[1]=0;
shan.push(make_pair(0,1));
while(!shan.empty()) {
int xx=shan.top().second;
shan.pop();
if(vis[xx]) continue;
vis[xx]=1;
for(register int i=head[xx];i;i=e[i].net) {
int v=e[i].to;
if(e[i].liu<li) continue;
if(dis[v]>dis[xx]+e[i].val) {
dis[v]=dis[xx]+e[i].val;
shan.push(make_pair(-dis[v],v));
}
}
}
} int main() {
scanf("%d%d%d",&n,&m,&x);
for(register int i=1;i<=m;i++) {
scanf("%d%d%d%d",&u,&v,&w,&c);
flag[i]=c;
add(u,v,w,c);
add(v,u,w,c);
}
for(register int i=1;i<=m;i++) {
dijkstra(flag[i]);
if(dis[n]!=20050206) ans=min(ans,dis[n]+x/flag[i]);
}
printf("%d",ans);
return 0;
}

自认为讲得还是很详细的,如果还有什么不懂的欢迎留言qwq

最后,感谢一下RHL大佬对我的指导


Milk Pumping G&Milk Routing S 题解的更多相关文章

  1. 洛谷 P5837 [USACO19DEC]Milk Pumping G (单源最短路,dijkstra)

    题意:有一\(n\)个点,\(m\)条边的双向图,每条边都有花费和流量,求从\(1\)~\(n\)的路径中,求\(max\frac{min(f)}{\sum c}\). 题解:对于c,一定是单源最短路 ...

  2. P5837 [USACO19DEC]Milk Pumping G

    题目描述 Farmer John 最近为了扩张他的牛奶产业帝国而收购了一个新的农场.这一新的农场通过一个管道网络与附近的小镇相连,FJ 想要找出其中最合适的一组管道,将其购买并用来将牛奶从农场输送到小 ...

  3. 【题解】[USACO19DEC]Milk Visits G

    题目戳我 \(\text{Solution:}\) 这题不要把思想局限到线段树上--这题大意就是求路径经过的值中\(x\)的出现性问题. 最开始的想法是值域线段树--看了题解发现直接\(vector\ ...

  4. 【luogu P3063 [USACO12DEC]牛奶的路由Milk Routing】 题解

    题目链接:https://www.luogu.org/problemnew/show/P3063#sub 我很好奇这道题为什么没被收入SPFA好题 #include <cstdio> #i ...

  5. 题解 P5837 【[USACO19DEC]Milk Pumping】

    这题其实想法挺简单的,因为他只需要简单的把每个点的花费和流量用dp记下来就好了 1.怎么记: 首先考虑dp的状态.由于所在的点和流量都要记,所以dp开二维,一维记所在的点,另一维记去哪 //dp[i] ...

  6. Milk Pumping

    今天第一次正式打个人定位赛,还是太菜,这题连枚举加最短路都没想到,显然菜是原罪. 题面: : 题解:其实方法很多,千万别浪到网络流用dinic求最大网络流求的最小费用,这题不一样.最大流/最小费用 不 ...

  7. P5838 [USACO19DEC]Milk Visits G

    发现是一道比较裸的树上莫队,于是就开始刚,然后发现好像是最难的一道题--(本题解用于作者加深算法理解,也欢迎各位的阅读) 题意 给你一棵树,树有点权,询问一条路径上是否有点权为 \(c\) 的点. 题 ...

  8. buaacoding_2018算法期末上机G题.地铁建设题解

    // 标注:本文旨在为博主确立一种题解的基本范式,以避免博主的题解流于AC代码的粘贴.此基本范式为:完整而简洁明了的思路及其推导说明,力图触及问题的本质并衍生对同类问题的思路分析,使得题解具有泛用性, ...

  9. BNUOJ48605International Collegiate Routing Contest 题解

    题目大意: 给你一些子网,求它们在整个网段的补集. 思路: 将子网转换成二进制建一棵Trie,直接DFS搜到没有了就记下来输出.注意:所给的子网会有交集,若搜到结尾就不向下搜了. 代码: #inclu ...

随机推荐

  1. Java实现 蓝桥杯 算法提高 p1001

    算法提高 P1001 时间限制:1.0s 内存限制:256.0MB 提交此题  当两个比较大的整数相乘时,可能会出现数据溢出的情形.为避免溢出,可以采用字符串的方法来实现两个大数之间的乘法.具体来说 ...

  2. Java实现 蓝桥杯VIP 算法训练 水仙花数

    这道题有两个方法,第一个就相对来说通俗易懂 第二个可以用到Java的一些方法 public class 水仙花数1 { public static void main(String[] args) { ...

  3. Java实现 LeetCode 386 字典序排数

    386. 字典序排数 给定一个整数 n, 返回从 1 到 n 的字典顺序. 例如, 给定 n =1 3,返回 [1,10,11,12,13,2,3,4,5,6,7,8,9] . 请尽可能的优化算法的时 ...

  4. Java实现 蓝桥杯VIP 算法训练 判定数字

    算法训练 判定数字 时间限制:1.0s 内存限制:512.0MB 编写函数,判断某个给定字符是否为数字. 样例输入 9 样例输出 yes import java.util.Scanner; publi ...

  5. Java实现 LeetCode 120 三角形最小路径和

    120. 三角形最小路径和 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] ...

  6. Java实现 蓝桥杯 历届试题 地宫取宝

    问题描述 X 国王有一个地宫宝库.是 n x m 个格子的矩阵.每个格子放一件宝贝.每个宝贝贴着价值标签. 地宫的入口在左上角,出口在右下角. 小明被带到地宫的入口,国王要求他只能向右或向下行走. 走 ...

  7. java实现第六届蓝桥杯胡同门牌号

    胡同门牌号 小明家住在一条胡同里.胡同里的门牌号都是连续的正整数,由于历史原因,最小的号码并不是从1开始排的. 有一天小明突然发现了有趣的事情: 如果除去小明家不算,胡同里的其它门牌号加起来,刚好是1 ...

  8. Ansible facts详解

    Ansible是一个系列文章,我会尽量以通俗易懂.诙谐幽默的总结方式给大家呈现这些枯燥的知识点,让学习变的有趣一些. Ansible系列博文直达链接:Ansible入门系列 前言 如果你跟着前面的文章 ...

  9. 对Activity启动模式的理解

    对Activity启动模式的理解 应用场景 在已打开多个Activity应用B的前提下,应用A调用应用B后点击返回按钮,需要直接返回到A应用,而不是打开B应用的上一个Activity 一个Task可以 ...

  10. “进大厂大半年,每个月都想走!”大公司 VS 小公司到底该如何选择?

    前言 江湖风云不断,有人吐槽阿里996,也有人吐槽华为狼性文化,这不,就看到有腾讯员工吐槽“进腾讯大半年,每个月都想走!” “和我一样,进去一周就想走”.“我都陷入自我怀疑了,以为自己适应不了大公司” ...