次短路
Posted ppprseter
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了次短路相关的知识,希望对你有一定的参考价值。
次短路
广泛一点的定义是:在数值上比最短路大的一条最小的路径长度(有点像前驱)
(1) 双向SPFA求次短路
思路:处理出始点S,终点T到每个点的最短路径长度。枚举每条边,用这条边所连接的两个点所对应分别到S和T的长度更新次短路。
感性证明:不可能有比部分最短路+一条边还短的路径了
参考代码:
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int N=5010;
const int M=100010;
int head[N],edge[M<<1],to[M<<1],next[M<<1],cnt;
void add(int u,int v,int w)
{
edge[++cnt]=w;to[cnt]=v;next[cnt]=head[u];head[u]=cnt;
}
int diss[N],dist[N],n,m,used[N],shor,ans;
queue <int > q;
void spfa()
{
q.push(1);
memset(diss,0x3f,sizeof(diss));
memset(used,0,sizeof(used));
diss[1]=0;
while(!q.empty())
{
int u=q.front();
q.pop();
used[u]=0;
for(int i=head[u];i;i=next[i])
{
int v=to[i],w=edge[i];
if(diss[v]>diss[u]+w)
{
diss[v]=diss[u]+w;
if(!used[v])
{
used[v]=1;
q.push(v);
}
}
}
}
q.push(n);
memset(dist,0x3f,sizeof(diss));
memset(used,0,sizeof(used));
dist[n]=0;
while(!q.empty())
{
int u=q.front();
q.pop();
used[u]=0;
for(int i=head[u];i;i=next[i])
{
int v=to[i],w=edge[i];
if(dist[v]>dist[u]+w)
{
dist[v]=dist[u]+w;
if(!used[v])
{
used[v]=1;
q.push(v);
}
}
}
}
ans=0x3f3f3f3f;
shor=diss[n];
for(int i=1;i<=n;i++)
for(int j=head[i];j;j=next[j])
{
int v=to[j],w=edge[j];
if(diss[i]+dist[v]+w!=shor)
ans=min(ans,diss[i]+dist[v]+w);
}
printf("%d
",ans);
}
int main()
{
scanf("%d%d",&n,&m);
int u,v,w;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w),add(v,u,w);
}
spfa();
return 0;
}
(2) Dijsktra求次短路
待更新...
以上是关于次短路的主要内容,如果未能解决你的问题,请参考以下文章