次短路小结

本文详细介绍了次短路算法的两种计算方法,包括在更新最短路时同步更新次短路的方法,以及在计算出最短路后再进行枚举的方法。通过具体的代码示例,深入解析了算法的实现细节。

次短路有两种计算方法。

方法一、更新最短路时同步更新次短路

对于一条端点为u、v的边,点v的次短路,要么是点u的次短路加边权,要么是点u的最短路加边权。
设两个数组,dist1存储最短路,dist2存储次短路,则存在下面的等式:
dist2[v]=min{dist2[u]+wdist1[u]+wdist1[u]+w>dist1[v] dist2[v]=min\left\{ \begin{array}{rcl} dist2[u]+w \\ dist1[u]+w&&{dist1[u]+w>dist1[v]} \\ \end{array} \right. dist2[v]=min{dist2[u]+wdist1[u]+wdist1[u]+w>dist1[v]
在更新最短路的同时更新次短路即可。

代码

void spfa()
{
	queue<int> q;
	memset(dist,INF,sizeof(dist));
	memset(dist2,INF,sizeof(dist2));
	dist[1]=0;
	book[1]=true;
	q.push(1);
	while(q.size())
	{
		int u=q.front();q.pop();
		book[u]=false;
		for(int i=0;i<G[u].size();i++)
		{
			int v=G[u][i].first,w=G[u][i].second;
			if(dist[v]>dist[u]+w)//更新最短路
			{
				dist2[v]=dist[v]; //同时更新次短路
				dist[v]=dist[u]+w;
				if(!book[v]) 
				{
					q.push(v);book[v]=true;
				}
			}
			if(dist2[v]>dist2[u]+w)
			{
				dist2[v]=dist2[u]+w;
				if(!book[v]) 
				{
					q.push(v);book[v]=true;
				}
			}
			if(dist2[v]>dist[u]+w && dist[u]+w>dist[v])
			{
				dist2[v]=dist[u]+w;
				if(!book[v]) 
				{
					q.push(v);book[v]=true;
				}
			}
		}
	}	
}

二、计算出最短路后再枚举

对于无向图,先从1跑一遍最短路,存储在dist1,再从n跑一遍最短路,存储在dist2,对于每一条边,计算dist1[u]+dist2[v]+w,从里面找出次短路。
等式如下:
ans=min⁡(ans,dist1[u]+dist2[v]+w) 满足:(dist1[u]+dist2[v]+w)&gt;dist1[n]ans=\min(ans,dist1[u]+dist2[v]+w) \text{ 满足:(dist1[u]+dist2[v]+w)&gt;dist1[n]}ans=min(ans,dist1[u]+dist2[v]+w) 满足:(dist1[u]+dist2[v]+w)>dist1[n]

代码

图的存储

//建图
typedef pair<int,int> P;
vector<P> G[N];
for(int i=1,x,y,z;i<=m;i++)
{
	scanf("%d%d%d",&x,&y,&z);
	G[x].push_back(make_pair(y,z));
	G[y].push_back(make_pair(x,z));
}

跑完最短路后,求次短路。

//dist1和dist2分别是起点为1和n的最短路径
int ans=0x3FFFFFFF;	
for(int i=1;i<=n;i++)
	for(int j=0;j<G[i].size();j++)
	{
		int w=G[i][j].second,v=G[i][j].first;
		if(dist[i]+dist2[v]+w>dist[n])
			ans=min(ans,dist[i]+dist2[v]+w);
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值