洛谷P1576最小花费(逆Dijkstra算法)

news/2024/5/18 22:53:05

背景:说实话,这题有点考建模思想,及对Dijkstra算法的理解

思路:因为转账间有手续费,即有一定损失比例,故边权均小于1(比例来说),而边的路权值非和,而是积,故边权相当于负(因为每次乘会使dis[i]变小)
而题目刚好求最大路,而边权又等价于全为负,不刚好是Dijkstra的逆运用吗?

原理:等价负权图,求最大路,Dijkstra算法

数据结构:优先队列

时间复杂度:o(mlogm)

代码如下:

点击查看代码
//背景:说实话,这题有点考建模思想,及对Dijkstra算法的理解
/*思路:因为转账间有手续费,即有一定损失比例,故边权均小于1(比例来说),而边的路权值非和,而是积,故边权相当于负(因为每次乘会使dis[i]变小)而题目刚好求最大路,而边权又等价于全为负,不刚好是Dijkstra的逆运用吗?*/
//原理:等价负权图,求最大路,Dijkstra算法
//数据结构:优先队列
//时间复杂度:o(mlogm)
#include <bits/stdc++.h>
using namespace std;
typedef struct edge//边结构体
{int to;double value;
}EDGE;
typedef struct situation//队列元素结构体
{int u;double d;
}SI;
struct cmp//自定义优先队列比较
{bool operator()(SI x,SI y){return x.d < y.d;}
};
void Solve()
{int n,m,x,y,a,b;double v;scanf("%d%d",&n,&m);//输入节点数及边数double dis[n+1];bool vis[n+1];vector<EDGE> e[n+1];memset(dis,0,sizeof(dis));//初始化为0!!!!(因为乘积)memset(vis,0,sizeof(vis));//初始化for (int i = 1;i<=m;i++)//建图{scanf("%d%d%lf",&x,&y,&v);e[x].push_back({y,1-(v/100)});e[y].push_back({x,1-(v/100)});}scanf("%d%d",&a,&b);//输入源点及终点dis[a] = 1;//初速化源点为1priority_queue<SI,vector<SI>,cmp> que;//建立优先队列que.push({a,dis[a]});//源点入队while(!que.empty())//Dijkstra算法{x = que.top().u;que.pop();if(vis[x]) continue;//如果已经在最大路集合中了,接下来不可能更优了,跳过vis[x] = true;//入集合for (auto v:e[x])//松弛与当前点有关的边{if(dis[v.to] < dis[x]*v.value)//注意这里的状态转移!!!乘积{dis[v.to] = dis[x]*v.value;//更新最大路que.push({v.to,dis[v.to]});//入队}}}double ans = 100.0/dis[b];//计算答案(最大路为到b的钱为a给的钱的百分比),故100/比例printf("%.8f\n",ans);//输出,保留8位小数
}
int main()
{int t = 1;while(t--){Solve();}return 0;
}
题解不易,多多支持!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hjln.cn/news/28247.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

overthewire - Bandit

随笔记 overthewire的密码会在一定周期更换。 Bandit Level 0 直接SSH连接2220端口 ssh -p 2220 bandit0@localhost 密码:bandit0ls 查看目录,看到readme,读取文件。 cat readme 获取bandit1密码 NH2SXQwcBdpmTEzi3bvBHMM9H66vVXjL Bandit Level 0 → Level 1 ls 查看目录下…

对C语言符号的一些冷门知识运用的剖析和总结

把概念和原理讲清楚、进阶、C语言符号符号 目录符号注释奇怪的注释C风格的注释无法嵌套一些特殊的注释注释的规则建议反斜杠\反斜杠有续行的作用,但要注意续行后不能添加空格回车也能起到换行的作用,那续行符的意义在哪?反斜杠的转义功能单引号和双引号字面值,字符串,字符,字…

k8s核心组件详解和分层架构

k8s核心组件master中的核心组件api-server(接口服务,基于rest风格开放k8s接口的服务) kube-controller-manager(管理各个类型的控制器,针对k8s中的各种资源进行管理)cloud-controller-manager(云控制管理器,第三方云平台提供的控制器,api对接管理功能) kube-scheduler…

前端框架开发之Niu框架——从零学框架的小白

起因: 从2018年6月一直到我重新提笔,6年时间。这六年时间,我见证了IT的兴衰,见证了小众框架LayUI框架的重新更新,见证了vue、angular、react等框架的主流。----博客园老牛大讲堂初衷: 今年我突发灵感,想要设计一个网站,作为程序员却"提笔忘字",就连最基本的…

Blazor流程编排的艺术:深入Z.Blazor.Diagrams库的使用与实践

为现代网页应用开发提供动力的其中一个重要方面就是前端框架的强大功能与灵活性。而在.NET生态中,Blazor以其独特的工作方式和优势逐渐获得了开发者们的青睐。今天,在这篇文章中,我将带你深入探索一个基于Blazor的优秀库——Z.Blazor.Diagrams,我们将了解它是如何帮助开发者…

【未整合】数学 day4.2

博弈论 Nim游戏 对于 \(n=2\),\(a_1=a_2\),后手可以“模仿”先手,使得后手必胜。 对于 \(a_1\ne a_2\),先手可以让自己进入“模仿期”,使得先手必胜。 结论:若 \(\oplus a_i=0\),先手必败,否则必胜。很神奇的东西,证明需要群论知识。 发现石子的合并满足上面四条性质,…

Jmeter内存溢出:java.lang.OutOfMemoryError: Java heap space解决思路

一、问题原因 用JMeter压测,有时候当模拟并发请求较大或者脚本运行时间较长时,JMeter会停止,报OOM(内存溢出)错误。原因是JMeter是一个纯Java开发的工具,内存由java虚拟机JVM管理,当内存回收不及时,堆内存不足时,就会报内存溢错误。 概念补充: 内存泄露:应用使用资源…

ABC352

A link\(x\)停不到,\(y\)能停到。 要先判断是从前往后还是从后往前。点击查看代码 #include<bits/stdc++.h>using namespace std;signed main(){int n,x,y,z;cin >> n >> x >> y >> z;if(x <= y){if(z > x&&z <= y) cout <…