Milk Pumping G&Milk Routing S 题解
Milk Pumping G&Milk Routing S
双倍经验时间
洛谷P5837 [USACO19DEC]Milk Pumping G
洛谷P3063 [USACO12DEC]Milk Routing S
题目模型
给定\(N\)个点和\(M\)条边,对于每条边,给定连接的两个端点以及这条边的花费和“流量”
设这条路径上所有边的花费总和为\(L\)
设这条路径上所有边中“流量”值最小的为\(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 题解的更多相关文章
- 洛谷 P5837 [USACO19DEC]Milk Pumping G (单源最短路,dijkstra)
题意:有一\(n\)个点,\(m\)条边的双向图,每条边都有花费和流量,求从\(1\)~\(n\)的路径中,求\(max\frac{min(f)}{\sum c}\). 题解:对于c,一定是单源最短路 ...
- P5837 [USACO19DEC]Milk Pumping G
题目描述 Farmer John 最近为了扩张他的牛奶产业帝国而收购了一个新的农场.这一新的农场通过一个管道网络与附近的小镇相连,FJ 想要找出其中最合适的一组管道,将其购买并用来将牛奶从农场输送到小 ...
- 【题解】[USACO19DEC]Milk Visits G
题目戳我 \(\text{Solution:}\) 这题不要把思想局限到线段树上--这题大意就是求路径经过的值中\(x\)的出现性问题. 最开始的想法是值域线段树--看了题解发现直接\(vector\ ...
- 【luogu P3063 [USACO12DEC]牛奶的路由Milk Routing】 题解
题目链接:https://www.luogu.org/problemnew/show/P3063#sub 我很好奇这道题为什么没被收入SPFA好题 #include <cstdio> #i ...
- 题解 P5837 【[USACO19DEC]Milk Pumping】
这题其实想法挺简单的,因为他只需要简单的把每个点的花费和流量用dp记下来就好了 1.怎么记: 首先考虑dp的状态.由于所在的点和流量都要记,所以dp开二维,一维记所在的点,另一维记去哪 //dp[i] ...
- Milk Pumping
今天第一次正式打个人定位赛,还是太菜,这题连枚举加最短路都没想到,显然菜是原罪. 题面: : 题解:其实方法很多,千万别浪到网络流用dinic求最大网络流求的最小费用,这题不一样.最大流/最小费用 不 ...
- P5838 [USACO19DEC]Milk Visits G
发现是一道比较裸的树上莫队,于是就开始刚,然后发现好像是最难的一道题--(本题解用于作者加深算法理解,也欢迎各位的阅读) 题意 给你一棵树,树有点权,询问一条路径上是否有点权为 \(c\) 的点. 题 ...
- buaacoding_2018算法期末上机G题.地铁建设题解
// 标注:本文旨在为博主确立一种题解的基本范式,以避免博主的题解流于AC代码的粘贴.此基本范式为:完整而简洁明了的思路及其推导说明,力图触及问题的本质并衍生对同类问题的思路分析,使得题解具有泛用性, ...
- BNUOJ48605International Collegiate Routing Contest 题解
题目大意: 给你一些子网,求它们在整个网段的补集. 思路: 将子网转换成二进制建一棵Trie,直接DFS搜到没有了就记下来输出.注意:所给的子网会有交集,若搜到结尾就不向下搜了. 代码: #inclu ...
随机推荐
- ASP.Net Web中Repeater怎么删除指定行
使用OnItemCommand事件 首先附上相关的代码 <asp:Repeater ID="Repeater1" runat="server" OnIte ...
- Java实现 蓝桥杯VIP 算法训练 明明的随机数
问题描述 明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N≤100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应 ...
- java实现还款计算
标题: 还款计算 银行贷款的等额本息还款方法是: 每月还固定的金额,在约定的期数内正好还完(最后一个月可能会有微小的零头出入). 比如说小明在银行贷款1万元.贷款年化利率为5%,贷款期限为24个月. ...
- Java实现 蓝桥杯 历届试题 地宫取宝
问题描述 X 国王有一个地宫宝库.是 n x m 个格子的矩阵.每个格子放一件宝贝.每个宝贝贴着价值标签. 地宫的入口在左上角,出口在右下角. 小明被带到地宫的入口,国王要求他只能向右或向下行走. 走 ...
- java实现第七届蓝桥杯打印数字
打印数字 打印数字 小明写了一个有趣的程序,给定一串数字. 它可以输出这串数字拼出放大的自己的样子. 比如"2016"会输出为: 00000 1 6666 2 0 0 1 1 6 ...
- Linux 日志管理简介
查看日志rsyslogd是否启动和自启动 ps aux | grep rsyslogd 查看自启动(CentOS 7使用,CentOS 6可以使用chkconfig命令) systemctl list ...
- 支持MMDVM的DMR手台
只要是数字机,都支持,但是,有便宜又好用的吗?当然有,店主做那么久肯定知道哪些机好用 1.MD760(UV双段) 刷固件支持#切换不同的TG,可以手动改机子的DMR ID,可以下载联系人,可以升级!关 ...
- 温故知新-多线程-Cache Line存在验证
文章目录 简述 缓存行Cache Line 验证CacehLine存在? 参考 你的鼓励也是我创作的动力 Posted by 微博@Yangsc_o 原创文章,版权声明:自由转载-非商用-非衍生-保持 ...
- 对Activity启动模式的理解
对Activity启动模式的理解 应用场景 在已打开多个Activity应用B的前提下,应用A调用应用B后点击返回按钮,需要直接返回到A应用,而不是打开B应用的上一个Activity 一个Task可以 ...
- 【网页设计】第四周 JavaSript
第四周 JSP 一 JSP概述 含义: Java Server Pages, 广泛使用的服务器端脚本语言之一:(运行在服务器端 BS结构) 由服务器端的JSP引擎执行JSP代码,然后将结果以HT ...