Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我如何使用bellman-ford算法返回所有权重相同的最短路径?_C++ - Fatal编程技术网

C++ 我如何使用bellman-ford算法返回所有权重相同的最短路径?

C++ 我如何使用bellman-ford算法返回所有权重相同的最短路径?,c++,C++,正如标题所说,我正在寻找的是打印“所有最短路径”,这些路径由重量决定 例如: 我们有一个边从0->1->3的图,它的权重为6,但是我们也有路径0->3,它的权重为6,下面的算法只返回第一条路径,我想知道是否可以同时返回两条或所有路径。还有一种更高效/优雅的打印最短路径的方法。我只是以这段代码为例,我的代码非常相似,但只从源点打印到最后一个顶点 这里有一个类似的问题,但是我不懂代码,因为我熟悉C++。 #include <iostream> #include <vector>

正如标题所说,我正在寻找的是打印“所有最短路径”,这些路径由重量决定

例如:

我们有一个边从0->1->3的图,它的权重为6,但是我们也有路径0->3,它的权重为6,下面的算法只返回第一条路径,我想知道是否可以同时返回两条或所有路径。还有一种更高效/优雅的打印最短路径的方法。我只是以这段代码为例,我的代码非常相似,但只从源点打印到最后一个顶点

<>这里有一个类似的问题,但是我不懂代码,因为我熟悉C++。
#include <iostream>
#include <vector>
#include <iomanip>
#include <climits>
using namespace std;

// Data structure to store graph edges
struct Edge
{
    int source, dest, weight;
};

// Recurive Function to print path of given vertex v from source vertex
void printPath(vector<int> const &parent, int v)
{
    if (v < 0)
        return;

    printPath(parent, parent[v]);
    cout << v << " ";
}

// Function to run Bellman Ford Algorithm from given source
void BellmanFord(vector<Edge> const &edges, int source, int N)
{
    // count number of edges present in the graph
    int E = edges.size();

    // distance[] and parent[] stores shortest-path (least cost/path)
    // information. Initially all vertices except source vertex have
    // a weight of infinity and a no parent

    vector<int> distance (N, INT_MAX);
    distance[source] = 0;

    vector<int> parent (N, -1);

    int u, v, w, k = N;

    // Relaxation step (run V-1 times)
    while (--k)
    {
        for (int j = 0; j < E; j++)
        {
            // edge from u to v having weight w     
            u = edges[j].source, v = edges[j].dest;
            w = edges[j].weight;

            // if the distance to the destination v can be
            // shortened by taking the edge u-> v
            if (distance[u] != INT_MAX && distance[u] + w < distance[v])
            {
                // update distance to the new lower value
                distance[v] = distance[u] + w;

                // set v's parent as u
                parent[v] = u;
            }
        }
    }

    // Run Relaxation step once more for Nth time to
    // check for negative-weight cycles
    for (int i = 0; i < E; i++)
    {
        // edge from u to v having weight w
        u = edges[i].source, v = edges[i].dest;
        w = edges[i].weight;

        // if the distance to the destination u can be
        // shortened by taking the edge u-> v       
        if (distance[u] != INT_MAX && distance[u] + w < distance[v])
        {
            cout << "Negative Weight Cycle Found!!";
            return;
        }
    }

    for (int i = 0; i < N; i++)
    {
        cout << "Distance of vertex " << i << " from the source is "
             << setw(2) << distance[i] << ". It's path is [ ";
        printPath(parent, i); cout << "]" << '\n';
    }
}

// main function
int main()
{
    // vector of graph edges as per above diagram
    vector<Edge> edges =
    {
        // (x, y, w) -> edge from x to y having weight w
        { 0, 1, 2 }, { 1, 3, 4 }, { 0, 3, 6 }
    };

    // Set maximum number of nodes in the graph
    int N = 5;

    // let source be vertex 0
    int source = 0;

    // run Bellman Ford Algorithm from given source
    BellmanFord(edges, source, N);

    return 0;
}
#包括
#包括
#包括
#包括
使用名称空间std;
//存储图边的数据结构
结构边
{
整数来源、目的地、重量;
};
//Recrive函数从源顶点打印给定顶点v的路径
无效打印路径(向量常量和父对象,int v)
{
if(v<0)
返回;
打印路径(父,父[v]);

从更抽象的角度来看,你有一些东西可以找到一个最小的东西,你想把它改变成所有其他东西都一样小。(同样的原则也适用于寻找最大的东西。不过,坚持“最小”会使解释更简单。)

许多寻找极端事物的算法在某些部分会问“A比B更极端”。例如,您可能会看到如下代码:

if ( A < B )
    smallest = A;

如何将此应用于贝尔曼福特?

幸运的是,代码的关键部分相对容易,因为有注释记录它。更难的部分是更改代码以跟踪多个结果,因为发现较短路径时会更新两条数据。看起来需要扩展的数据是
parent
。下面是一个新的声明:

vector< vector<int> > parent (N);
这与一般方法稍有不同,因为没有“
else
”。这是相同的逻辑,只是排列有点不同。请注意,当输入第一个
if
子句时,距离向量会更新,因此第二个
if
子句也会被输入

我认为处理找到的路径是一个单独的问题(不是一个简单的问题),因此我将把它留给您来解决如何更新
printPath()
。不过,我将给出一个保留旧输出的版本(只是最短路径中的第一条)这与其说是一个建议,不如说是一个将新数据结构与旧数据结构联系起来的说明

// Recursive function to print the path of (just) the first given vertex from source vertex.
void printPath(vector< vector<int> > const &parent, vector<int> const &vlist)
{
    if (vlist.empty())
        return;

    int v = vlist.front();
    printPath(parent, parent[v]);
    cout << v << " ";
}
//递归函数,用于从源顶点打印(仅)第一个给定顶点的路径。
无效打印路径(向量<向量>常量和父对象,向量常量和向量列表)
{
if(vlist.empty())
返回;
int v=vlist.front();
打印路径(父,父[v]);
库特
if (distance[u] != INT_MAX) {
    // if the distance to the destination v can be
    // shortened by taking the edge u-> v
    if (distance[u] + w < distance[v])
    {
        // update distance to the new lower value
        distance[v] = distance[u] + w;
        // forget the previous parent list.
        parent[v].clear();
    }
    // if u-> v is a way to get the shortest
    // distance to the destination v.
    if (distance[u] + w == distance[v])
    {
        // add u as a possible parent for v
        parent[v].push_back(u);
    }
}
// Recursive function to print the path of (just) the first given vertex from source vertex.
void printPath(vector< vector<int> > const &parent, vector<int> const &vlist)
{
    if (vlist.empty())
        return;

    int v = vlist.front();
    printPath(parent, parent[v]);
    cout << v << " ";
}