博客
关于我
【最短路Dijkstra】【图论】最小花费
阅读量:361 次
发布时间:2019-03-04

本文共 1796 字,大约阅读时间需要 5 分钟。

为了解决这个问题,我们需要找到一个路径,使得A转账给B后B收到100元的总费用最少。我们可以将这个问题看作是一个图的最短路径问题,但由于涉及百分比扣除,我们需要用一种变形后的最短路径算法来解决。

方法思路

  • 问题分析:我们需要计算从A转到B的最优路径,使得在扣除手续费后B收到100元。每次转账都会扣除一定的百分比手续费,因此我们需要找到使总扣除费率最大的路径。

  • 转换问题:将每次转账的百分比手续费转换为保留比例,然后将问题转化为寻找从A到B的最大扣除费率路径。这样,总费用最少的路径就是使得保留比例最大的路径。

  • 算法选择:使用优先队列(大顶堆)来实现一种变形后的Dijkstra算法。我们记录从A到每个节点的最大扣除费率,并不断更新邻居节点的最大扣除费率。

  • 实现步骤

    • 读取输入数据并构建图的邻接表。
    • 初始化最大保留比例数组和优先队列。
    • 使用优先队列处理每个节点,更新邻居节点的最大保留比例。
    • 计算最终的金额,使得B收到100元。
  • 解决代码

    import heapqdef main():    import sys    input = sys.stdin.read    data = input().split()        idx = 0    n = int(data[idx])    idx += 1    m = int(data[idx])    idx += 1    graph = [[] for _ in range(n + 1)]    for _ in range(m):        x = int(data[idx])        idx += 1        y = int(data[idx])        idx += 1        z = float(data[idx])        idx += 1        ratio = 1.0 - z / 100.0        graph[x].append((y, ratio))        graph[y].append((x, ratio))        A = int(data[idx])    idx += 1    B = int(data[idx])    idx += 1    max_ratio = [0.0] * (n + 1)    max_ratio[A] = 1.0    heap = []    heapq.heappush(heap, (-1.0, A))    while heap:        current_ratio = -heap[0][0]        u = heap[0][1]        if u == B:            break        if current_ratio < max_ratio[u]:            continue        for v, ratio in graph[u]:            new_ratio = current_ratio * ratio            if new_ratio > max_ratio[v]:                max_ratio[v] = new_ratio                heapq.heappush(heap, (-new_ratio, v))    required = 100.0 / (1.0 - max_ratio[B])    print("{0:.8f}".format(required))if __name__ == "__main__":    main()

    代码解释

  • 读取输入:使用sys.stdin.read读取所有输入数据,并将其拆分为列表处理。
  • 构建图邻接表:读取每条转账关系,构建图的邻接表,其中每条边的权重是转账后的保留比例。
  • 初始化变量max_ratio数组记录从A到每个节点的最大扣除费率,优先队列用于处理节点,按当前最大保留比例排序。
  • 处理优先队列:每次取出当前最大保留比例的节点,更新其邻居节点的最大保留比例,并将邻居节点加入队列。
  • 计算结果:根据最大保留比例计算A需要支付的金额,使得B收到100元,并输出结果,精确到8位小数。
  • 转载地址:http://muug.baihongyu.com/

    你可能感兴趣的文章
    Opencv Sift和Surf特征实现图像无缝拼接生成全景图像
    查看>>
    opencv SVM分类Demo
    查看>>
    OpenCV VideoCapture.get()参数详解
    查看>>
    opencv videocapture读取视频cap.isOpened 输出总是false
    查看>>
    opencv waitKey() 函数理解及应用
    查看>>
    OpenCV 中的图像转换
    查看>>
    OpenCV 人脸识别 C++实例代码
    查看>>
    OpenCV 在 Linux 上的 python 与 anaconda 无法正常工作.收到未实现 cv2.imshow() 的错误
    查看>>
    Opencv 完美配置攻略 2014 (Win8.1 + Opencv 2.4.8 + VS 2013)上
    查看>>
    opencv 模板匹配, 已解决模板过大程序不工作的bug
    查看>>
    OpenCV 错误:(-215)size.width>0 &&函数imshow中的size.height>0
    查看>>
    opencv&Python——多种边缘检测
    查看>>
    opencv&python——高通滤波器和低通滤波器
    查看>>
    OpenCV+Python识别车牌和字符分割的实现
    查看>>
    OpenCV-Python接口、cv和cv2的性能比较
    查看>>
    OpenCV/Python/dlib眨眼检测
    查看>>
    opencv1-加载、修改、保存图像
    查看>>
    opencv10-形态学操作
    查看>>
    opencv11-提取水平直线和垂直直线
    查看>>
    opencv12-图像金字塔
    查看>>