将具有边缘权重的Multigraph减少为具有最小边缘权重的简单图形

时间:2018-07-16 20:48:54

标签: c++ performance input dijkstra

我有一条最短路径问题: 给定一个具有n个顶点的图,找到从顶点1到顶点n的最短路径(以获取的边数为单位,而不是边的权重),如果这些路径中有多个,则采用词典顺序最小的路径的边缘权重。

输入由nmn顶点和m边(2 <= n <= 100.000; 1 <= m <= 200.000)组成m边缘。 两个顶点之间可以有多个边。这是我第一次使用C ++,来自Java。


我当前的输入/主要内容如下:

ios::sync_with_stdio(false);
int n, m, v1, v2, w;
vector<string> outvec;
while (infile >> n >> m) {
    int k = 0;

    for (int i = 0; i < m; i++) {
        infile >> v1 >> v2 >> w;
        //TODO Only add smallest edge between 2 vertices
        if (v1 != v2) {
            adj[v1].push_back(make_pair(v2, w));
            adj[v2].push_back(make_pair(v1, w));
        }
    }

    dijkstra(n + 1);

    string outs;
    while (n != 1) {
        outs.insert(0, to_string(col[n]) + " ");
        n = previ[n];
        k++;
    }
    outs = outs.substr(0, outs.length() - 1);
    outvec.push_back(to_string(k).append("\n").append(outs).append("\n"));
    for (auto& v : adj) {
        v.clear();
    }           
}

其中adj代表邻接列表,确切地说是array中的vector<pair<int,int>>


毕竟,我使用Dijkstra's Algorithm作为具有上述2个指标的最短路径。但是对于所需的情况,它仍然太慢。

我的想法是,将两个顶点之间的最大边数减少为一个,同时将所有边的权重最小,这样Dijkstra不需要遍历两个顶点之间的所有边。

有没有一种有效的方法可以实现我的目标?迪克斯特拉(Dijkstra)是去这里的方式吗?


所以我的问题是我在运行时的性能,这也是我在dijkstra上的当前实现:

void dijkstra(int m) {
    for (int i = 0; i < m; i++) {
        dis[i] = INT_MAX;
        col[i] = INT_MAX;
        previ[i] = -1;
        vis[i] = false;
    }
    dis[1] = 0;
    priority_queue<pair<int, double>, vector<pair<int, double> >, cmp> q;
    q.push(make_pair(1, 0));
    while (!q.empty()) {
        pair<int, double> currPair = q.top();
        q.pop();
        int currVertex = currPair.first;
        double currWeight = currPair.second;

        if (vis[currVertex]) {
            continue;
        }
        else if (currVertex == m - 1) {
            break;
        }

        vis[currVertex] = true;
        for (int i = 0; i < adj[currVertex].size(); i++) {
            int nextVertex = adj[currVertex][i].first;
            int nextEdgeCol = adj[currVertex][i].second;
            int currEdgeCol = col[nextVertex];

            if (!vis[nextVertex]) {
                pair<int, int> newP;
                if (currWeight + 1 < dis[nextVertex]) {
                    previ[nextVertex] = currVertex;
                    dis[nextVertex] = currWeight + 1;
                    col[nextVertex] = nextEdgeCol;
                    newP = make_pair(nextVertex, dis[nextVertex]);
                }
                else if (currWeight + 1 == dis[nextVertex]) {
                    if (col[nextVertex] > nextEdgeCol) {
                        previ[nextVertex] = currVertex;
                        dis[nextVertex] = currVertex + 1;
                        col[nextVertex] = nextEdgeCol;
                        newP = make_pair(nextVertex, dis[nextVertex]);
                    }
                }
                q.push(newP);
            }
        }
    }
}

有关该问题的更多信息,请查看here

0 个答案:

没有答案