【问题标题】:Shortest path between 2 nodes in DAG unweighedDAG 中 2 个节点之间的最短路径未加权
【发布时间】:2020-04-09 23:00:41
【问题描述】:
#include <bits/stdc++.h>

#define MAX_NODES 1005
#define INFINITE 
using namespace std;

vector<int> graph[MAX_NODES];
int numOfVertices, numOfEdges;

int shortest_path[MAX_NODES][MAX_NODES]; // shortest_path[i][j] holds the shortest path between i and j

int k;

int shortestPath(int i, int j) {
    // k ++;
    if (i == j) 
        shortest_path[i][j] = 1;

    // if we didn't solve shortest_path between i and j before

        // than solve it
    if (!shortest_path[i][j]) {

        int min_path = 10e6;
        for (auto vertice : graph[i])
            min_path = min(min_path, shortestPath(vertice, j) + 1);


        shortest_path[i][j] = min_path;
    }
    return shortest_path[i][j];
}

// the graph will be directed
void read() {
    int x, y; // temporary variables to read vertices and store them in our "graph"
    cin >> numOfVertices >> numOfEdges;

    for (int i = 0;i < numOfEdges;i ++) {
        cin >> x >> y;
        graph[x].push_back(y);
    }
}

void print() {
    for (int i = 0;i < numOfVertices;i ++) {
        if (graph[i].size())
            cout << i << " : ";
        for (int j = 0;j < graph[i].size();j ++) {
            cout << graph[i][j] << ' ';
        }
        if (graph[i].size())
            cout << '\n';
    }
}


int main() {
    freopen("input.in", "r", stdin);
    freopen("output.out", "w", stdout);

    // ios_base :: sync_with_stdio(false);
    // cin.tie(NULL);
    // cout.tie(NULL);

    read();
    // print();

    int i = 1;
    int j = 7;
    int answer = shortestPath(i, j);

    if (answer == 10e6)
        printf("There are no paths between vertice %d and vertice %d\n", i, j);
    else
        printf("Shortest path between vertice %d and vertice %d ins: %d\n", i, j, answer - 1);

    // cout << k << endl;
    return 0;
}

上述程序计算未加权 DAG 中 2 个顶点之间的最短路径。

shortest_path[i][j] = 顶点 i 和顶点 j 之间的最短路径。

函数int shortestPath(int i, int j)的复杂度是多少?

我认为是 O(V + E),其中 V 是顶点数和 E 边数,但我不知道如何证明。

【问题讨论】:

标签: c++ graph shortest-path


【解决方案1】:

请注意,j 在函数调用中没有变化,因此函数的复杂性仅取决于 i

shortest_path[i][j] = min_path 正在完成两件事:保存从ij 的最小路径并标记i 已访问(因为j 没有改变)。因此,曾经访问过的顶点将不会被再次访问。

所以shortest_path 将被调用为不同的值i 可以让我们称之为N 这是图中顶点的总数。因此,最小时间复杂度至少为O(N)。在每次调用中,for 循环都会针对outdegree of vertex i 运行。现在添加所有顶点的for循环成本,它将是outdegree of V1 + outdegree of V2 + ... + outdegree of Vn,等于O(E)。因此总时间复杂度为O(N + E)

【讨论】:

  • 如果没有 memoization,你认为我的函数复杂度会是多少?
【解决方案2】:

如果我们不计算已经计算出当前节点距离的调用,显然最多有V 函数调用。忽略递归调用的函数调用的复杂度与节点的邻居数成线性关系,因此这些调用的总复杂度为O(E)

对于已经计算出当前节点距离的调用,图中每条边都会发生恒定数量的调用,因此复杂度为O(E)。这给出了O(E) 的综合复杂度。

虽然函数调用的复杂度是O(E),但您的shortest_path 数组有V^2 元素,因此单独创建数组是O(V^2)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-04
    • 2021-12-18
    • 2015-02-19
    相关资源
    最近更新 更多