洛谷P2865 [USACO06NOV]Roadblocks G(次短路)

一个次短路的问题,可以套用dijkstra求最短路的方法,用dis[0][i]表示最短路;dis[1][i]表示次短路,优先队列中存有最短路和次短路,然后每次找到一条道路对他进行判断,更新最短或次短路,

注意求次短路时不要打标记,因为有可能再次访问到该节点。

最后的答案就是dis[1][n]。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 200010
 4 int tot,head[N],to[N],w[N],nxt[N],n,m,dis[3][N];
 5  
 6 void add(int x,int y,int z){
 7     nxt[++tot]=head[x];head[x]=tot;
 8     to[tot]=y;w[tot]=z;
 9 }
10  
11 struct node{//建立优先队列 
12     int pos,dis;
13     friend bool operator<(node a,node b){
14         return a.dis>b.dis;
15     }
16 }tmp;
17  
18 priority_queue<node> q;
19  
20 void dij(){
21     for(int i=1;i<=n;i++){
22         dis[0][i]=dis[1][i]=2147483647;
23     }
24     dis[0][1]=0;
25     tmp.dis=0;tmp.pos=1;
26     q.push(tmp);
27     while(!q.empty()){
28         tmp=q.top();q.pop();
29         int u=tmp.pos,d=tmp.dis;
30         if(d>dis[1][u]) continue;//比最短路和次短路还要小,直接跳过 
31         for(int i=head[u];i;i=nxt[i]){
32             int v=to[i];
33             if(dis[0][v]>d+w[i]){//比最短路小,更新最短路和次短路 
34                 dis[1][v]=dis[0][v];
35                 tmp.dis=dis[0][v]=d+w[i];
36                 tmp.pos=v;
37                 q.push(tmp);
38             }
39             if(dis[1][v]>d+w[i]&&dis[0][v]<d+w[i]){//更新次短路 
40                 tmp.dis=dis[1][v]=d+w[i];
41                 tmp.pos=v;
42                 q.push(tmp);
43             }
44         }
45     }
46 }
47  
48 int main(){
49     cin>>n>>m;
50     for(int i=1;i<=m;i++){
51         int a,b,c;
52         cin>>a>>b>>c;
53         add(a,b,c);add(b,a,c);
54     }
55     dij();
56     cout<<dis[1][n];//输出起点到终点的次短路 
57 }

 

posted @ 2022-04-04 14:33  YHXo  阅读(82)  评论(0编辑  收藏  举报