洛谷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 }