【问题标题】:Infinite loop in my Dijkstra algorithm implementation [closed]我的 Dijkstra 算法实现中的无限循环[关闭]
【发布时间】:2014-08-31 03:00:01
【问题描述】:

我正在为在线裁判编程竞赛编写程序。这是一个简单的 dijkstra 最短路径问题,但我在这里遇到了一个非常奇怪的问题。

在我阅读我的输入(注释为#PROBLEM)后,CPU 使用率达到 100%,并且程序不执行任何其他操作:既不接受新输入也不显示任何输出。奇怪的是,如果我注释掉我的cins 旁边的dijkstra() 函数调用,问题就无法再次重现。

我正在考虑 UB,但在这里真的找不到问题所在。

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
#define INF 100001
#define vi vector<int>
#define ii pair<int, int>
#define vii vector<ii>

struct orderByCost {
 bool operator() (ii a, ii b) { return a.second > b.second; }
};

int dijkstra(const vector<vii> &adj, int start, int target) {
    vector<bool> visited(adj.size());
    priority_queue<ii, vector<ii>, orderByCost> pq;
    pq.push(ii(start, 0));
    vi costsTable(adj.size(), INF);
    while (!pq.empty()) {
        ii node = pq.top(); pq.pop();
        if (visited[node.first]) {
            continue;
        }
        visited[start] = true;
        for (int i = 0; i < adj[node.first].size(); i++)
        {
            ii neighbor = adj[node.first][i];
            if (!visited[neighbor.first]) {
                pq.push(neighbor);
            }
            if (costsTable[neighbor.first] == INF) {
                costsTable[neighbor.first] = neighbor.second;
            } else if (neighbor.second + costsTable[node.first] < costsTable[neighbor.first]) {
                costsTable[neighbor.first] += costsTable[node.first];
            }
        }
    }

    return costsTable[target];
}

int main(int argc, char *argv[]) {
    int n, e;
    while (true) {
        cin >> n >> e;
        if (n == e && e == 0) break;
        vector<vii> adj(n);
        for(int i = 0; i < e; i++)    {
            int a, b, w;
            cin >> a >> b >> w;
            a--; b--;
            adj[a].push_back(ii(b, w));
        }
        int cases;
        cin >> cases;
        for(int i = 0; i < cases; i++) {
            int a, b;
            cin >> a >> b; // #PROBLEM: this is the input that causes weird behavior
            a--; b--;
            int result = dijkstra(adj, a, b); // #PROBLEM: if I comment this line out, the following line WILL get printed. If not, CPU use get's 100% and just hangs
            cout << "This line isn't being printed\n";
            result > 0 ? cout << result << '\n' : cout << "Not possible\n";
        }
    }
}

输入示例(注意: 以 # 开头的行是我为您理解而制作的 cmets,它们不是输入的一部分):

4 5 # 4 nodes with 5 edges
1 2 5 # edge from node 1 to node 2 with cost of 5
2 1 10
3 4 8
4 3 7
2 3 6
5 # test cases
1 2 # cost from path 1 to 2. Here is where the input hangs
1 3
1 4
4 3
4 1
3 3

读取输入后我的 CPU 使用情况:

【问题讨论】:

  • 听起来你在dijkstra() 函数中有一个无限循环,嗯?
  • 用适当的常数值替换 cin 输入。重新评估情况并更正标题。
  • 当。我想我们都去过一次……我完全错过了。

标签: c++ dijkstra


【解决方案1】:

你可能想改变

visited[start] = true;

进入

visited[node.first] = true;

否则只有 start 节点被标记为已访问。

【讨论】:

  • 好吧,这有点尴尬。我花了相当长的时间并没有意识到这一点。感谢您指出。但是,如果我在 dijkstra 函数调用的开头添加了对 std::cout 的调用,则它不会在错误版本中打印出来。这可能是编译器干预吗?
  • 这可能是因为要打印的行仍在缓冲区中,尚未刷新。您可以使用std::cerr 再试一次。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-05
相关资源
最近更新 更多