次短路

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

点击打开链接

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

#include 
#include 
#include 
#include 
#include 
#define INF 0xfffffff
using namespace std;

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

void solve(){
    priority_queue,greater

> 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   
    #include   
    #include   
    #include   
    #include   
    #include   
    #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 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;  
    }  


你可能感兴趣的:(待解决,次短路)