首页 > 编程语言 >洛谷P1576最小花费(逆Dijkstra算法)

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

时间:2024-05-05 16:22:32浏览次数:19  
标签:洛谷 int P1576 算法 vis Dijkstra que dis

背景:说实话,这题有点考建模思想,及对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;//初速化源点为1
    priority_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;
}

题解不易,多多支持!!

标签:洛谷,int,P1576,算法,vis,Dijkstra,que,dis
From: https://www.cnblogs.com/cuijunjie18/p/18173587

相关文章

  • 洛谷题单指南-动态规划2-P1435 [IOI2000] 回文字串
    原题链接:https://www.luogu.com.cn/problem/P1435解题思路:方法1:回文字串的特点是,正着读、反着读是一样的换一个思路,对于一个字符串s,正序、逆序公共的部分就是已经是回文的部分,剩余的部分就是要插入的字符所以,问题转换为,计算一个字符串正序、逆序的最长公共子串,然后剩下的长度......
  • 洛谷P2375 [NOI2014] 动物园
    动物园题目描述输入格式输出格式输入输出样例输入3aaaaaababcababc输出36132开始时都没看出来这是kmp板子题先看看AC代码吧#include<bits/stdc++.h>#definelllonglongusingnamespacestd;constintmaxn=1e6+10;constintmod=1e9+7;chara[maxn];in......
  • #交互,dp#洛谷 7998 [WFOI - 01] 猜数(guess)
    题目传送门分析首先要搞清楚,交互库的自适应会让区间长度尽可能增大(答案自适应)也就是说,如果现在区间为\([l,r]\),你选取的区间为\([l',r']\),那么交互库会让你的区间变成\([l,r'-1]\)和\([l'+1,r]\)中区间更长的那一个,不妨枚举这个长度设\(dp[i]\)表示区间长度为\(i\)......
  • 洛谷2664树上游戏-点分治
    link:https://www.luogu.com.cn/problem/P2664lrb有一棵树,树的每个节点有个颜色。给一个长度为\(n\)的颜色序列,定义\(s(i,j)\)为\(i\)到\(j\)的颜色数量。以及\[sum_i=\sum_{j=1}^ns(i,j)\]现在他想让你求出所有的\(sum_i\)。一个暴力的想法:因为是求和,所以可以拆......
  • 洛谷题单指南-动态规划2-P1091 [NOIP2004 提高组] 合唱队形
    原题链接:https://www.luogu.com.cn/problem/P1091题意解读:要挑选一个最长的先上升后下降的序列,求其余的元素数量解题思路:先计算正向的最长上升子序列,设f[i]表示以i结尾的正向最长上升子序列再计算逆向的最长上升子序列,设g[i]表示以i结尾的逆向最长上升子序列再枚举所有的i<j,m......
  • 洛谷 P5293 [HNOI2019] 白兔之舞
    洛谷传送门所求即为:\[\begin{aligned}f_t&=\sum\limits_{m=0}^L\binom{L}{m}A^m[k\midm-t]\\&=\frac{1}{k}\sum\limits_{m=0}^L\binom{L}{m}A^m\sum\limits_{i=0}^{k-1}\omega_k^{i(m-t)}\\&=\frac{1}{k}\sum\l......
  • 洛谷题单指南-动态规划2-P1004 [NOIP2000 提高组] 方格取数
    原题链接:https://www.luogu.com.cn/problem/P1004题意解读:从起点走到终点,走两次,计算最大路径和,第一次走过的点数值变为0。解题思路:直观上思考,可以先从起点走到终点,计算最大路径和,并记录走过的所有点,然后把所有点的数值置为0,再从起点走到终点,计算最大路径和,把两次的最大路径......
  • 洛谷 P10084 [GDKOI2024 提高组] 计算
    洛谷传送门第一步是一个经典结论,\(L=m^{\gcd(a,b)}+1\),\(R=m^{\gcd(c,d)}\)。因为\(L\equiv1\pmodm\)且\(R\equiv0\pmodm\),所以可以把问题的范围改成\([1,n=R-L+1]\)。写出选数的生成函数:\[F(x)=\prod\limits_{i=1}^n(1+x^i)\]我们希望求......
  • 题解:洛谷 P1137 旅行计划
    标签:图论,拓扑,dp题意给定一张\(n\)个点\(m\)条边的DAG,对于每个\(i\),求以它为终点最多经过多少个点?思路由于是DAG,求的是终点\(i\)经过的所有点,而刚好拓扑序就满足这个。那么就可以考虑拓扑排序。设\(f_i\)是以\(i\)为终点的最多结点数,那么就有转移方程\(f_v=m......
  • 洛谷P5597 复读
    洛谷P5597复读首先概括一下题意:文中给出三个指令L(命令机器人向当前节点的左子节点走)、R(命令机器人向当前节点的右子节点走)、U(命令机器人向当前节点的父亲节点走)以及一颗二叉树。初始状态,机器人在二叉树的根节点。当机器人处于二叉树的根节点时,不可以执行指令U,但是机器人可以走......