D65 最短路 Dijkstra 算法 P1576 最小花费
D65 最短路 Dijkstra 算法 P1576 最小花费_哔哩哔哩_bilibili
在 n 个人中,某些人的银行账号之间可以互相转账。这些人之间转账的手续费各不相同。给定这些人之间转账时需要从转账金额里扣除百分之几的手续费,请问 A 最少需要多少钱使得转账后 B 收到 100 元。
思路
两个人之间实际的汇率是 $1-z \%$,我们将人看做点,汇率看做边权。
如果 $A$ 到 $B$ 的汇率是 $x$ ,$B$ 到 $C$ 的汇率是 $y$ ,那么 $A$ 到 $C$ 的汇率就是 $x*y$。
我们用 Dijkstra 算法 求汇率的最长路,把方程中的加改为乘。
答案就是汇率最大,费用最少。
相关板子:
D02【模板】最短路 Dijkstra 算法 P4779 单源最短路径 - 董晓 - 博客园
// 最短路 Dijkstra 算法 O(mlogn) #include<bits/stdc++.h> using namespace std; const int N=2005; int n,m,s,t; vector<pair<double,int>> e[N]; int vis[N]; double d[N]; void dijkstra(){ priority_queue<pair<double,int>> q; //大根堆 q.emplace(d[s]=1,s); while(q.size()){ int u=q.top().second; q.pop(); if(vis[u]) continue; vis[u]=1; for(auto [w,v]:e[u]){ if(d[v]<d[u]*w) q.emplace(d[v]=d[u]*w,v); //d[v]从s到v的最大汇率 } } } int main(){ cin>>n>>m; for(int i=0,x,y,z; i<m; i++){ cin>>x>>y>>z; double p=(100.0-z)/100; //汇率 e[x].emplace_back(p,y); e[y].emplace_back(p,x); } cin>>s>>t; dijkstra(); //计算汇率的最长路 printf("%.8lf\n",100/d[t]); //汇率最大,费用最小 }
浙公网安备 33010602011771号