本题目的意思就是要求次短路。我用两种方法求解:
(一)利用dijkstra算法进行适当修改,到某个顶点v的次短路:(1)其他某个顶点u的最短路加上u->v的边长;(2)其他某个顶点u的次短路加上u->v的边长。所以我们要求出到所有
顶点的最短路和次短路。因此对每个顶点,同时记录最短距离和次短距离(开两个数组记录,用dijkstra算法不断更新)。
[cpp]
view plain
copy
- #include<queue>
- #include<vector>
- #include<iostream>
- #include<stdio.h>
- #include<string.h>
- #include<algorithm>
- using namespace std;
- const int INF=1000000000;
- const int max_e=200000+5;
- typedef pair<int,int>P;
- struct edge{
- int to,dis;
- edge(int to,int dis){
- this -> to = to;
- this -> dis = dis;
- }
- };
- int N,R;
- int a,b,c;
- int dis[5005]; //记录最短路径
- int disc[5005]; //记录次短路径
- vector<edge>G[max_e];
- void dijkstra(){
- fill(dis+1,dis+N+1,INF);
- fill(disc+1,disc+N+1,INF);
- priority_queue<P,vector<P>,greater<P> >q;
- dis[1]=0;
- q.push(P(0,1));
- while(q.size()){
- P p=q.top();
- q.pop();
- int dd=p.first;
- int v=p.second;
- if(disc[v]<dd) continue;
- for(int i=0;i<G[v].size();i++){
- edge& e=G[v][i];
- int d=dd+e.dis;
- if(dis[e.to]>d){
- swap(dis[e.to],d);
- q.push(P(dis[e.to],e.to));
- }
- if(disc[e.to]>d&&dis[e.to]<d){ //这里是关键改动!
- disc[e.to]=d;
- q.push(P(disc[e.to],e.to));
- }
- }
- }
- cout<<disc[N]<<endl;
- }
- int main()
- {
- scanf(“%d%d”,&N,&R);
- for(int i=1;i<=R;i++){
- scanf(“%d%d%d”,&a,&b,&c);
- G[a].push_back(edge(b,c));
- G[b].push_back(edge(a,c));
- }
- dijkstra();
- return 0;
- }
(二)一个巧妙的方法,用两次dijkstra双向求出起点到每一点的最短路,以及终点到每一点的最短路径,然后枚举每一条边,就可以得到次短路了。此方法也可以拓展成求第K短
路问题,不过要注意时间复杂度。
[cpp]
view plain
copy
- #include<queue>
- #include<vector>
- #include<iostream>
- #include<stdio.h>
- #include<string.h>
- #include<algorithm>
- using namespace std;
- const int INF=1000000000;
- const int max_e=200000+5;
- typedef pair<int,int>P;
- struct edge{
- int to,dis;
- edge(int to,int dis){
- this -> to = to;
- this -> dis = dis;
- }
- };
- struct dd{
- int x,y;
- int sum;
- }an[200005];
- int N,R;
- int a,b,c;
- int d1[5005];
- int d2[5005];
- vector<edge>G[max_e];
- void dijkstra(int dis[],int s){
- fill(dis+1,dis+N+1,INF);
- priority_queue<P,vector<P>,greater<P> >q;
- dis[s]=0;
- q.push(P(0,s));
- while(q.size()){
- P p=q.top();
- q.pop();
- int v=p.second;
- if(dis[v]<p.first) continue;
- for(int i=0;i<G[v].size();i++){
- edge& e=G[v][i];
- if(dis[e.to]>dis[v]+e.dis){
- dis[e.to]=dis[v]+e.dis;
- q.push(P(dis[e.to],e.to));
- }
- }
- }
- }
- int main()
- {
- int K=0;
- scanf(“%d%d”,&N,&R);
- for(int i=1;i<=R;i++){
- scanf(“%d%d%d”,&a,&b,&c);
- G[a].push_back(edge(b,c));
- G[b].push_back(edge(a,c));
- an[K].x=a; an[K].y=b; an[K].sum=c; K++;
- an[K].x=b; an[K].y=a; an[K].sum=c; K++;
- }
- dijkstra(d1,1);
- dijkstra(d2,N);
- int ans=INF; //cout<<ans<<” “<<d1[N]<<endl;
- for(int i=0;i<K;i++){
- int aa=d1[an[i].x]+d2[an[i].y]+an[i].sum; //这里是关键!!!!
- if(aa>d1[N]){ //如果大于最短路,那就比较,取最小的就是次短路
- ans=min(ans,aa);
- }
- }cout<<ans<<endl;
- return 0;
- }