【多校训练】hdu 6181 Two Paths 次短路径 Dijkstra

本文介绍了一种求解次短路径问题的方法,通过Dijkstra算法的改进来找到从起点到终点的次短路径,并提供了完整的C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem Description
You are given a undirected graph with n nodes (numbered from 1 to n) and m edges. Alice and Bob are now trying to play a game. 
Both of them will take different route from 1 to n (not necessary simple).
Alice always moves first and she is so clever that take one of the shortest path from 1 to n.
Now is the Bob's turn. Help Bob to take possible shortest route from 1 to n.
There's neither multiple edges nor self-loops.
Two paths S and T are considered different if and only if there is an integer i, so that the i-th edge of S is not the same as the i-th edge of T or one of them doesn't exist.
 

Input
The first line of input contains an integer T(1 <= T <= 15), the number of test cases.
The first line of each test case contains 2 integers n, m (2 <= n, m <= 100000), number of nodes and number of edges. Each of the next m lines contains 3 integers a, b, w (1 <= a, b <= n, 1 <= w <= 1000000000), this means that there's an edge between node a and node b and its length is w.
It is guaranteed that there is at least one path from 1 to n.
Sum of n over all test cases is less than 250000 and sum of m over all test cases is less than 350000.
 

Output
For each test case print length of valid shortest path in one line.
 

Sample Input
2 3 3 1 2 1 2 3 4 1 3 3 2 1 1 2 1
 

Sample Output
5 3
Hint
For testcase 1, Alice take path 1 - 3 and its length is 3, and then Bob will take path 1 - 2 - 3 and its length is 5. For testcase 2, Bob will take route 1 - 2 - 1 - 2 and its length is 3
 

题意:

求次短路径

思路:

不仅保存最短路径值,也保存次短路径值。每次比较更新最短路和次短路,套个次短路径的模版即可。

//
//  main.cpp
//  1011
//
//  Created by zc on 2017/8/24.
//  Copyright © 2017年 zc. All rights reserved.
//

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#define ll long long
using namespace std;
const int MAXN=110000;
const ll inf=0x3f3f3f3f3f3f3f3f;
struct Edge{
    int v;
    ll w;
};
vector<Edge>vet[MAXN];
struct Node{
    int v;
    ll dist;
    int mark;
    bool operator < (const Node &p) const {
        if(p.dist!=dist)
            return p.dist<dist;
        
        return p.v<v;
    }
};
int n,m,s,e;
ll dist[MAXN][3];
bool visited[MAXN][3];

void Dijkstra(int start,int end){
    for(int i=1;i<=n;i++){
        dist[i][1]=dist[i][2]=inf;
    }
    memset(visited,false,sizeof(visited));
    priority_queue<Node>Q;
    Node p,q;
    dist[start][1]=0;
    p.dist=0,p.mark=1,p.v=start;
    Q.push(p);
    while(!Q.empty()){
        p=Q.top();
        Q.pop();
        if(visited[p.v][p.mark])continue;
        //if(dist[p.v][p.mark]!=p.dist)continue;
        visited[p.v][p.mark]=true;
        for(int i=0;i<vet[p.v].size();i++){
            int v=vet[p.v][i].v;
            ll w=vet[p.v][i].w;
            if(!visited[v][1]&&p.dist+w<dist[v][1]){
                //可能为次短路
                if(dist[v][1]!=inf){
                    q.v=v,q.dist=dist[v][1],q.mark=2;
                    dist[v][2]=dist[v][1];
                    Q.push(q);
                }
                dist[v][1]=p.dist+w;
                q.v=v,q.dist=dist[v][1],q.mark=1;
                Q.push(q);
            }else if(!visited[v][2]&&p.dist+w<dist[v][2]){
                dist[v][2]=p.dist+w;
                q.dist=dist[v][2],q.v=v,q.mark=2;
                Q.push(q);
            }
        }
    }
}



int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        s=1;e=n;
        for(int i=0;i<=n;i++)vet[i].clear();
        for(int i=1;i<=m;i++){
            int u,v;
            ll w;
            scanf("%d%d%lld",&u,&v,&w);
            Edge p;
            p.v=v,p.w=w;
            vet[u].push_back(p);
            p.v=u;
            vet[v].push_back(p);
        }
        Dijkstra(s,e);
        printf("%lld\n",dist[e][2]);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值