好题分享:luogu P5837 [USACO19DEC]Milk Pumping G

好题分享

luogu P5837 [USACO19DEC]Milk Pumping G

读完题后,人们会自然想到,这就是最短路板子题,只不过判断的条件改一下而已。但是自信一交,发现只得 20 p t s 20pts 20pts(特指 d i j dij dij堆优化)。此时,我们调试后发现,本题与正常的最短路有点不一样,那就是:一个点在被更新后,还能被再次更新!!!

也就是说,我们代码中 v i s vis vis数组的标记是毫无作用的。为什么会出现这种情况呢??因为本题中的“最短路”与两个值有关:价值(V)和花费(C)。但是,我们堆里面用于比较的,却只有他们的比值。

意思是:对于某一个点来说,它的 V ÷ C V \div C V÷C的值可能较大,就导致它会更早的去更新其他点。但是此时,被他更新的点不一定是最优解·。

这就是本题的坑点所在。具体见 c o d e : code: code:

#include<bits/stdc++.h> using namespace std; const int maxn = 1005; typedef double db; int n, m; struct my_str { int to, nxt; db val, cost; }edge[maxn * 2]; int head[maxn], tot = 0; db dis[maxn]; bool vis[maxn]; struct my_str1 { int loc; db value, costcost, road; friend bool operator <(my_str1 a, my_str1 b) { return a.road > b.road; } }; priority_queue < my_str1 > qq; struct picture { inline void add(int x, int y, int z, int c) { edge[++ tot].nxt = head[x]; edge[tot].to = y; edge[tot].cost = 1.0 * c; edge[tot].val = 1.0 * z; head[x] = tot; } void Dij() { dis[1] = 0; my_str1 F; F.loc = 1; F.costcost = 0.0; F.value = 0x7f7f7f7f; F.road = 0x7f7f7f7f; qq.push(F); while(!qq.empty()) { my_str1 Top = qq.top(); qq.pop(); int Loc = Top.loc; db Val = Top.value; db Cost = Top.costcost; db Road = Top.road; vis[Loc] = 1; for(int i = head[Loc]; i != -1; i = edge[i].nxt) { int To = edge[i].to; db CC = edge[i].cost; db VV = edge[i].val; if(min(VV, Val) / (CC + Cost) > dis[To]) { my_str1 mark = Top; mark.loc = To; mark.value = min(VV, Val); mark.costcost = CC + Cost; mark.road = mark.value / mark.costcost; dis[To] = mark.road; qq.push(mark); } } } } }pic; struct node { inline int read() { int x = 0, f = 1; char ch = getchar(); while(!isdigit(ch)) { if(ch == '-') f = -1; ch = getchar(); } while(isdigit(ch)) { x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar(); } return x * f; } void work() { n = node::read(), m = node::read(); memset(head, -1, sizeof head); for(int i = 1; i <= m; i ++) { int x = node::read(), y = node::read(), z = node::read(), c = node::read(); pic.add(x, y, c, z); pic.add(y, x, c, z); } pic.Dij(); printf("%.0lf", floor(dis[n] * 1000000.0)); } }code; int main() { code.work(); return 0; }

__EOF__

本文作者best_brain
本文链接https://www.cnblogs.com/best-brain/p/18006575.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   best_brain  阅读(4)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示