不谷尉 2022-01-22 17:49 采纳率: 0%
浏览 24
已结题

PTA A1003 Bellman-Ford算法统计最短路径数的两个方法,法二好使(满分),法一不太好使(扣三分)

作者在跟着算法笔记学习Bellman-Ford算法时,使用该算法完成PTA的A1003题Emergency(代码如下)在统计最短路径时,由于贝尔曼福特算法会多次访问每一条边,这使得其会多次得到最短路径的前驱,故使用容器set去重。在统计最短路径数量时,使用迭代器遍历set,累加前驱的最短路径数量成功得到正确结果,而使用另一个方法在每次向set集合中插入元素时获取返回值,在插入成功时同时累加前驱结点的最短路径数量却无法总是得到正确结果,这是什么原因呢?
问题相关代码
//
// Created by BuGuWei on 2022/1/22.
//
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
const int MAXV = 500, INF = 0x3fffffff;

struct Node{
    int v, dis;
    Node(int _v, int _dis) : v(_v), dis(_dis){};
};
int n, m, c1, c2, weight[MAXV];
vector<Node> Adj[MAXV];
int d[MAXV], w[MAXV] = {0}, num[MAXV] = {0};
set<int> pre[MAXV];
using namespace std;
void bellman(int s);
int main() {
    scanf("%d%d%d%d", &n, &m, &c1, &c2);
    for(int i = 0; i < n; i++) {
        scanf("%d", &weight[i]);
    }
    int a, b, l;
    for(int j = 0; j < m; j++){
        //         Node* tempNode = new Node();
        scanf("%d%d%d", &a, &b, &l);
        Adj[a].push_back(Node(b, l));
        Adj[b].push_back(Node(a, l));
    }
    //    dijkstra(c1);
    bellman(c1);
    printf("%d %d\n", num[c2], w[c2]);
    return 0;
}

void bellman(int s) {
    fill(d, d + n, INF);
    fill(w, w + n, 0);
    fill(num, num + n, 0);
    d[s] = 0;
    w[s] = weight[s];
    num[s] = 1;
    for(int i = 0; i < n; i++) {
        for(int u = 0; u < n; u++) {
            for(int j = 0; j < Adj[u].size(); j++) {
                int v = Adj[u][j].v, dis = Adj[u][j].dis;
                if(d[u] + dis < d[v]) {
                    d[v] = d[u] + dis;
                    w[v] = w[u] + weight[v];
                    num[v] = num[u];
                    pre[v].clear();
                    pre[v].insert(u);
                } else if(d[u] + dis == d[v]) {
                    if(w[u] + weight[v] > w[v]){
                        w[v] = w[u] + weight[v];
                    }

                    // 法一
                    if(pre[v].insert(u).second) {
                        num[v] += num[u];
                    }

                    // 法二
//                    pre[v].insert(u);
//                    num[v] = 0;
//                    set<int>::iterator it;
//                    for(it = pre[v].begin(); it != pre[v].end(); it++) {
//                        num[v] += num[*it];
//                    }
                }
            }
        }
    }

}


运行结果及报错内容

法一

img


法二

img

我的解答思路

即每次插入最短路径成功时计算当前最短路径数量。

希望有da shen能刷到我的问题并斧正,万谢!
  • 写回答

1条回答 默认 最新

  • 有问必答小助手 2022-01-24 15:07
    关注

    你好,我是有问必答小助手,非常抱歉,本次您提出的有问必答问题,技术专家团超时未为您做出解答


    本次提问扣除的有问必答次数,将会以问答VIP体验卡(1次有问必答机会、商城购买实体图书享受95折优惠)的形式为您补发到账户。


    因为有问必答VIP体验卡有效期仅有1天,您在需要使用的时候【私信】联系我,我会为您补发。

    评论

报告相同问题?

问题事件

  • 系统已结题 1月30日
  • 创建了问题 1月22日

悬赏问题

  • ¥30 设计一个图形用户界面来控制你机械臂的运动
  • ¥30 3d打印机无法识别到SD卡,如何解决?(相关搜索:格式化)
  • ¥15 RPG游戏架构设计和开发方法
  • ¥15 python 计算股权结构
  • ¥30 为什么会失败呢,该如何调整
  • ¥15 前端返回pdf时不显示内容
  • ¥50 如何在不能联网影子模式下的电脑解决usb锁
  • ¥20 服务器redhat5.8网络问题
  • ¥15 如何利用c++ MFC绘制复杂网络多层图
  • ¥20 要做柴油机燃烧室优化 需要保持压缩比不变 请问怎么用AVL fire ESE软件里面的 compensation volume 来使用补偿体积来保持压缩比不变