题解 P1576 【最小花费】
算法:Dijkstra+堆优化(题解里为什么没有啊。。。,spfa能不用就千万别用,这个算法非常地危险) 思路其他题解都已经讲的很清楚了,我们来讲一下具体代码如何实现:
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
int n,m,A,B;
double dis[2010];
bool mark[2010];
struct Node//固定格式:因为最短路里面是从小到大,那么最长路就要反过来,从大到小
{
int Num;
double dis;
bool operator<(const Node &a) const
{
return a.dis>dis;//再次提醒
}
};
struct node
{
int Num;
double dis;
};
vector<node> G[2010];
inline void Dij()
{
priority_queue<Node> q;//建立优先队列
Node temp;
temp.Num=A;
temp.dis=1;
q.push(temp);//初始化
while(!q.empty())//Dij算法,不会请自行百度了解基本思想
{
int u=q.top().Num;//取出队首的元素
q.pop();
if(mark[u]==1) continue;
mark[u]=1;
for(int i=0;i<G[u].size();i++)//讨论与队首元素相关的点
{
int v=G[u][i].Num;
double l=G[u][i].dis;
if(mark[v]==0&&dis[v]<dis[u]*l)//最长路更新
{
dis[v]=dis[u]*l;
temp.Num=v;
temp.dis=dis[v];
q.push(temp);//入队
}
}
}
}
int main()
{
node temp;
scanf("%d%d",&n,&m);//输入点,边
memset(dis,-0x3f,sizeof(dis));//因为是求最长路,所以初始化为负无穷
for(int i=1;i<=m;i++)
{
int x,y;
double z;
scanf("%d%d%lf",&x,&y,&z);//输入一条线的两端以及长度
temp.Num=y;
temp.dis=1-z/100;
G[x].push_back(temp);
temp.Num=x;
G[y].push_back(temp);//双向边,用的vector存图,链式前向星同理
}
scanf("%d%d",&A,&B);//输入起始点,终止点
dis[A]=1;//起始点到自己的距离要初始化为1,不能是0,否则等下与之相乘的数就会是0了
Dij();//跑
printf("%.8lf",100/dis[B]);//输出答案
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构