poj 3255 最短路和次短路

来源:互联网 发布:非局部均值去噪算法 编辑:程序博客网 时间:2024/04/28 19:22

题意:

  • 求从起点到终点的次短路

Bellman-Ford算法:

  • 把有向图的边存起来,然后每次扫描所有边,来更新起点到每个点的最短路,当这一次扫描,一次更新都没有的时候,说明所有顶点的最短路已经求得。复杂度是O(|E||V|)。根据这个思想还可以来判断图中存不存在负圈。

Dijkstra算法(戴克斯特拉):

  • 1.初始所有顶点都是未使用过,且除了起点最短距离为0外,所有顶点最短距离都为INF。
  • 2.找出所有未使用顶点中,最短距离最小的点,由它更新出所有和它相连顶点的最短路。
  • 3.重复2步骤,直到所有顶点都被使用过。
    这种方法的实现复杂度是O(|V|2),还可以优化。

  • 如果用一个优先队列把所有未使用过且最短距离(还不一定是最终最短距离)已知的顶点存起来,每次取队列底部的那个元素扩展,并将扩展得到的元素全部插入优先队列,这样删除插入的效率都是O(log|V|),整个算法的效率就是O(|E|log|V|)

我的思路:

  • 先求出到所有顶点的最短路。然后次短路无非是由最短路加上一条边,或最短路加上一条边得来,据此法则求次短路。要注意可以先到终点然后回去,再到终点。比如只有两个顶点,一个边的图,次短路是三倍边长。我的方法中,更新次短路用到的是Bellman-Ford算法的思想。

书上的思路:

  • 书上用的Dijstra算法实现,用dist[v]记录最短路,dist2[v]记录次短路,这样每次都按照规则更新最短路和次短路即可。

心得:

  • 学习算法的时候不要想着记忆具体实现,而是只关注抽象思维部分,具体实现由抽象思维得出即可
#include <set>#include <map>#include <cmath>#include <stack>#include <queue>#include <string>#include <vector>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;typedef long long int LL;const int M = 10009,INF = 0x3fffffff;int v, e;struct edge { int from, to, cost; }E[300009];pair<int, int> d[M];void input(void) {    for (int i = 0; i < e / 2; i++) {        scanf("%d%d%d", &E[i].from, &E[i].to, &E[i].cost);        E[i].from--;        E[i].to--;        E[e / 2 + i].from = E[i].to;        E[e / 2 + i].to = E[i].from;        E[e / 2 + i].cost = E[i].cost;    }}int second_shortest_path(void) {    for (int i = 0; i < v; i++) { d[i].first = d[i].second = INF; }    d[0].first = 0;    edge temp;    while (true) {        bool update = false;        for (int i = 0; i < e; i++) {            temp = E[i];            if (d[temp.from].first != INF && d[temp.to].first > d[temp.from].first + temp.cost) {                d[temp.to].first = d[temp.from].first + temp.cost;                update = true;            }        }        if (!update) break;    }    while (true) {        bool update = false;        for (int i = 0; i < e; i++) {            temp = E[i];            //if (temp.from == v - 1) continue;            if (d[temp.from].first != INF) {                if (d[temp.to].second > d[temp.from].second + temp.cost && d[temp.from].second + temp.cost > d[temp.to].first) {                    d[temp.to].second = d[temp.from].second + temp.cost;                    update = true;                }                if (d[temp.to].second > d[temp.from].first + temp.cost && d[temp.from].first + temp.cost > d[temp.to].first) {                    d[temp.to].second = d[temp.from].first + temp.cost;                    update = true;                }            }        }        //cout << d[ v -1].first << endl;        if (!update && d[v - 1].second != INF) break;    }    return d[v - 1].second;}int main(void) {    //problem: , address:    while (~scanf("%d%d", &v, &e)) {        e = e * 2;        input();        printf("%d\n", second_shortest_path());    }    return 0;}
0 0
原创粉丝点击