且未

博客园 首页 新随笔 联系 订阅 管理

找了好半天才找到两个比较好理解的代码,暂时放到这,之后再来改。

点击打开链接

次短路[v]=最短路[u]+边[u,v] 或者 次短路[v]=次短路[u]+边[u,v] ,不同于普通最短路,我们需要维护两个数组:最短路+次短路。
我这里采用 邻接表+dijkstra,不断更新最短路和次短路。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#define INF 0xfffffff
using namespace std;

struct Edge{
    int to,cost;
};
int n,r;
vector<Edge> edge[5005];
typedef pair<int,int> P;//first是最短距离,second是顶点编号
int dis1[5005];//最短距离
int dis2[5005];//次短距离

void solve(){
    priority_queue<P,vector<P>,greater<P> > q;//递增的优先队列
    for(int i = 0; i <= n; i++){
        dis1[i] = INF;
        dis2[i] = INF;
    }
    dis1[1] = 0;
    q.push(P(0,1));
    while(!q.empty()){
        P p = q.top();
        q.pop();
        int v = p.second,d = p.first;
        if(dis2[v] < d)
            continue;
        for(int i = 0; i < edge[v].size(); i++){
            Edge &e = edge[v][i];
            int d2 = d + e.cost;
            //最短距离的更新,入队
            if(dis1[e.to] > d2){
                    printf("dis1[e.to]=%d > d2=%d ?\n",e.to,d2);
                swap(dis1[e.to],d2);
                q.push(P(dis1[e.to],e.to));
            }
            //新的次短距离 应该 大于最短距离&&小于原来的次短距离
            if(dis2[e.to] > d2 && dis1[e.to] < d2){
                printf("dis2[e.to]=%d > d2=%d ?\n",e.to,d2);
                dis2[e.to] = d2;
                q.push(P(dis2[e.to],e.to));//入队
            }
        }
    }
    printf("%d\n",dis2[n]);
}

int main(){
    while(~scanf("%d%d",&n,&r)){
        for(int i = 0; i <= n; i++)
            edge[i].clear();
        int u,v,cost;
        Edge tmp;
        for(int i = 0; i < r; i++){
            scanf("%d%d%d",&u,&v,&cost);
            tmp.to = v;tmp.cost = cost;
            edge[u].push_back(tmp);
            tmp.to = u;
            edge[v].push_back(tmp);
        }
        solve();
    }
    return 0;
}

点击打开链接http://blog.csdn.net/qq_21899803/article/details/52192736

先算出每个点到1的最短路dis[i],再算出每个点到n点的最短路disr[i],然后枚举所有边,计算次短路dis[u]+disr[v]+edge[u][v]

#include <cstdio>  
    #include <cstring>  
    #include <iostream>  
    #include <algorithm>  
    #include <cstring>  
    #include <queue>  
    #define MAXN 5010  
    #define MAXM 101000  
    #define INF 0x3f3f3f3f  
    using namespace std;  
      
    struct node  
    {  
        int v, w, next;  
    } edge[MAXM * 2];  
      
    int n, m, e, p, q;  
    int vis[MAXN], dis[MAXN], disr[MAXN], head[MAXN];  
      
    void insert(int x, int y, int w)  
    {  
        edge[e].v = y;  
        edge[e].w = w;  
        edge[e].next = head[x];  
        head[x] = e++;  
    }  
      
    void spfa(int src, int d[])  
    {  
        memset(vis, 0, sizeof(vis));  
        vis[src] = 1;  
        d[src] = 0;  
        queue<int> Q;  
        Q.push(src);  
        while(!Q.empty())  
        {  
            p = Q.front();  
            Q.pop();  
            vis[p] = 0;  
            for(int i = head[p]; i != -1; i = edge[i].next)  
            {  
                int v = edge[i].v;  
                int w = edge[i].w;  
                if(d[v] > d[p] + w)  
                {  
                    d[v] = d[p] + w;  
                    if(!vis[v])  
                    {  
                        vis[v] = 1;  
                        Q.push(v);  
                    }  
                }  
            }  
        }  
    }  
      
    int main()  
    {  
        int a, b, c;  
        while(scanf("%d%d", &n, &m) != EOF)  
        {  
            e = 0;  
            memset(head, -1, sizeof(head));  
            memset(dis, 0x3f, sizeof(dis));  
            memset(disr, 0x3f, sizeof(dis));  
            for(int i = 0; i < m; i++)  
            {  
                scanf("%d%d%d", &a, &b, &c);  
                insert(a, b, c);  
                insert(b, a, c);  
            }  
            spfa(1, dis);  
            spfa(n, disr);  
            int mini = dis[n];  
            int ans = INF;  
            for(int i = 1; i <= n; i++)  
            {  
                for(int j = head[i]; j != -1; j = edge[j].next)  
                {  
                    int v = edge[j].v;  
                    int w = edge[j].w;  
                    if(dis[i] + disr[v] + w > mini && dis[i] + disr[v] + w < ans)  
                        ans = dis[i] + disr[v] + w;  
                }  
            }  
            printf("%d\n",ans);  
        }  
        return 0;  
    }  


posted on 2017-11-02 18:45  阿聊  阅读(143)  评论(0编辑  收藏  举报