次短路 - Roadblocks - 一本通 3.2 练习 2

在这里插入图片描述

样例

输入

4 4
1 2 100
2 4 200
2 3 250
3 4 100

输出

450

解题思路:用两个数组(一个dis存最短路,一个diss存次短路)来spfa当找到最短路的时候将此时最短路赋值给次短路,最短路再更改,即

if(dis[p[i].to]>val+p[i].val)
{
	diss[p[i].to]=dis[p[i].to];
	dis[p[i].to]=val+p[i].val;
	q.push({p[i].to,dis[p[i].to]});
	q.push({p[i].to,diss[p[i].to]});
}

当此时需要判断的路径大于最短路但小于次短路时更改,即

if(diss[p[i].to]>val+p[i].val&&val+p[i].val>dis[p[i].to])
{
	diss[p[i].to]=val+p[i].val;
	q.push({p[i].to,diss[p[i].to]});
}

需要用到的

用pair来将两个变量存到队列中typedef pair<int,int> pll;
创建优先队列priority_queue<pll,vector<pll>,greater<pll> >q;

完整代码如下:

#include<queue>
#include<stdio.h>
#include<string.h>
using namespace std;
typedef pair<int,int> pll;
const int N=1e6+10,inf=1e9+10;
int dis[N],diss[N],head[N],cnt=1;
struct px
{
	int to,val,net;
} p[N];
void add(int from,int to,int val)
{
	p[cnt].to=to;
	p[cnt].val=val;
	p[cnt].net=head[from];
	head[from]=cnt++;
}
void spfa()
{
	int val,to;
	priority_queue<pll,vector<pll>,greater<pll> >q;
	memset(dis,inf,sizeof(dis));
	memset(diss,inf,sizeof(diss));
	q.push({1,0});
	dis[1]=0;
	while(!q.empty())
	{
		pll v=q.top();
		q.pop();
		to=v.first;
		val=v.second;
		for(int i=head[to]; i!=-1; i=p[i].net)
		{
			if(dis[p[i].to]>val+p[i].val)
			{
				diss[p[i].to]=dis[p[i].to];
				dis[p[i].to]=val+p[i].val;
				q.push({p[i].to,dis[p[i].to]});
				q.push({p[i].to,diss[p[i].to]});
			}
			if(diss[p[i].to]>val+p[i].val&&val+p[i].val>dis[p[i].to])
			{
				diss[p[i].to]=val+p[i].val;
				q.push({p[i].to,diss[p[i].to]});
			}
		}
	}
}
int main()
{
	int n,m,a,b,c;
	memset(head,-1,sizeof(head));
	scanf("%d %d",&n,&m);
	while(m--)
	{
		scanf("%d %d %d",&a,&b,&c);
		add(a,b,c);add(b,a,c);
	}
	spfa();
	printf("%d",diss[n]);
}
posted @ 2021-12-05 15:56  新城R  阅读(85)  评论(0)    收藏  举报