【次短路模板】习题
一.模板
dis[t][0]:表示 s ss 到 t tt 的最短路;
dis[t][1] dis[t][1]dis[t][1]:表示 s ss 到 t tt 的次短路;
堆优化的Dijkstra模板
#include<bits/stdc++.h> using namespace std; #define maxn 1000010 #define INF 0x3f3f3f3f typedef long long ll; typedef pair<ll,int>pii; struct Edge{ int to,nxt; ll w; }edge[maxn<<2]; ll dis[maxn][2]; int n,m,s,t,tot=0,vis[maxn],head[maxn]; void add(ll u,ll v,ll w){ edge[++tot].to=v; edge[tot].w=w; edge[tot].nxt=head[u]; head[u]=tot; edge[++tot].to=u; edge[tot].w=w; edge[tot].nxt=head[v]; head[v]=tot; } void Dijkstra(){ for(int i=0;i<=n;i++) dis[i][0]=dis[i][1]=INF; dis[s][0]=0; priority_queue<pii,vector<pii>,greater<pii> >que; que.push(pii(0,s)); while(!que.empty()){ pii p=que.top(); que.pop(); if(p.first>dis[p.second][1]) continue; for(int i=head[p.second];~i;i=edge[i].nxt){ ll d=p.first+edge[i].w; if(dis[edge[i].to][0]>d){//更新最短路 swap(dis[edge[i].to][0],d);//交换!!! que.push(pii(dis[edge[i].to][0],edge[i].to));//注意d值已经被交换了 } if(dis[edge[i].to][1]>d&&dis[edge[i].to][0]<d){//更新次短路 dis[edge[i].to][1]=d; que.push(pii(d,edge[i].to)); } } } } int main(){ tot=0,memset(head,-1,sizeof(head)); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ ll u,v,w; scanf("%lld%lld%lld",&u,&v,&w); add(u,v,w); } scanf("%d%d",&s,&t); //起点,终点 Dijkstra(); printf("%lld %lld\n",dis[t][0],dis[t][1]);//最短路,次短路 return 0; }
第二种版本:
#include <bits/stdc++.h> using namespace std; #define res register int #define inf 0x3f3f3f3f const int maxn=5005; int N,M,ans=1; int head[maxn]; int dis1[maxn],dis2[maxn]; struct Node{ int x,sum; }; bool operator<(const Node a,const Node b){ return a.sum>b.sum; } struct edge{ int to,next,val; }e[100005*2]; void add(int x,int y,int val){ e[ans].to=y; e[ans].val=val; e[ans].next=head[x]; head[x]=ans++; } void dijkstra() { priority_queue<Node> q; q.push((Node){1,0}); while(!q.empty()){ Node now=q.top(); q.pop(); int from=now.x,sum=now.sum; if(dis2[from]<sum) continue;//加上了这个神奇的东西。 for(res i=head[from];i;i=e[i].next){ int to=e[i].to; int temp=sum+e[i].val; if(dis1[to]>temp){ swap(dis1[to],temp); q.push((Node){to,dis1[to]}); } if(dis2[to]>temp&&dis1[to]<temp){ dis2[to]=temp; q.push((Node){to,dis2[to]}); } } } } void init() { scanf("%d%d",&N,&M); int v1,v2,val; for(res i=1;i<=M;i++){ scanf("%d%d%d",&v1,&v2,&val); add(v1,v2,val); add(v2,v1,val); } fill(dis1,dis1+N+1,inf); fill(dis2,dis2+N+1,inf); dis1[1]=0; } int main() { init(); dijkstra(); printf("%d",dis2[N]); return 0; }
spfa模板
#include<bits/stdc++.h> using namespace std; #define maxn 1000010 #define INF 0x3f3f3f3f typedef long long ll; struct Edge{ int to,nxt; ll w; }edge[maxn<<2]; ll dis[maxn][2]; int n,m,s,t,tot=0,vis[maxn],head[maxn]; void add(ll u,ll v,ll w){ edge[++tot].to=v; edge[tot].w=w; edge[tot].nxt=head[u]; head[u]=tot; edge[++tot].to=u; edge[tot].w=w; edge[tot].nxt=head[v]; head[v]=tot; } void spfa(){ for(int i=1;i<=n;i++) vis[i]=0,dis[i][0]=dis[i][1]=INF; dis[s][0]=0; queue<int>q; q.push(s); vis[s]=1; while(!q.empty()){ int u=q.front(); q.pop(); vis[u]=0; for(int i=head[u];~i;i=edge[i].nxt){ ll v=edge[i].to,w=edge[i].w; if(dis[v][0]>dis[u][0]+w){ dis[v][1]=dis[v][0]; dis[v][0]=dis[u][0]+w; if(!vis[v]){ vis[v]=1; q.push(v); } } if(dis[v][1]>dis[u][0]+w && dis[u][0]+w>dis[v][0]){ dis[v][1]=dis[u][0]+w; if(!vis[v]){ vis[v]=1; q.push(v); } } if(dis[v][1]>dis[u][1]+w){ dis[v][1]=dis[u][1]+w; if(!vis[v]){ vis[v]=1; q.push(v); } } } } } int main(){ tot=0,memset(head,-1,sizeof(head)); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ ll u,v,w; scanf("%lld%lld%lld",&u,&v,&w); add(u,v,w); } scanf("%d%d",&s,&t); spfa(); printf("%lld %lld\n",dis[t][0],dis[t][1]); return 0; }
二.习题
1.P2865 [USACO06NOV]路障Roadblocks ---三种都行 去掉最短路的输出
#include<bits/stdc++.h> using namespace std; #define maxn 1000010 #define INF 0x3f3f3f3f typedef long long ll; struct Edge{ int to,nxt; ll w; }edge[maxn<<2]; ll dis[maxn][2]; int n,m,s,t,tot=0,vis[maxn],head[maxn]; void add(ll u,ll v,ll w){ edge[++tot].to=v; edge[tot].w=w; edge[tot].nxt=head[u]; head[u]=tot; edge[++tot].to=u; edge[tot].w=w; edge[tot].nxt=head[v]; head[v]=tot; } void spfa(){ for(int i=1;i<=n;i++) vis[i]=0,dis[i][0]=dis[i][1]=INF; dis[s][0]=0; queue<int>q; q.push(s); vis[s]=1; while(!q.empty()){ int u=q.front(); q.pop(); vis[u]=0; for(int i=head[u];~i;i=edge[i].nxt){ ll v=edge[i].to,w=edge[i].w; if(dis[v][0]>dis[u][0]+w){ dis[v][1]=dis[v][0]; dis[v][0]=dis[u][0]+w; if(!vis[v]){ vis[v]=1; q.push(v); } } if(dis[v][1]>dis[u][0]+w && dis[u][0]+w>dis[v][0]){ dis[v][1]=dis[u][0]+w; if(!vis[v]){ vis[v]=1; q.push(v); } } if(dis[v][1]>dis[u][1]+w){ dis[v][1]=dis[u][1]+w; if(!vis[v]){ vis[v]=1; q.push(v); } } } } } int main(){ tot=0,memset(head,-1,sizeof(head)); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ ll u,v,w; scanf("%lld%lld%lld",&u,&v,&w); add(u,v,w); } s=1,t=n; spfa(); printf("%lld\n",dis[t][1]); return 0; }

浙公网安备 33010602011771号