luogu P2865 [USACO06NOV]路障Roadblocks

背景:

好久之前的题目了 . . . ... ...

题目传送门:

https://www.luogu.org/problemnew/show/P2865

题意:

求严格次短路。

思路:

本来是一道 s p f a spfa spfa傻逼题。
仔细一想发现好像之前的思路有问题,那就来细讲一下吧。
d i s i , 0 dis_{i,0} disi,0表示最短路, d i s i , 1 dis_{i,1} disi,1表示次短路。
考虑当前能否更新最短路。若可以则更新当前次短路和最短路;否则,考虑更新次短路。
如何更新次短路,我原来一直以为用上一次的最短路更新即可,但只有 50 p t s 50pts 50pts,细想一下发现要还用上次的次短路更新。
见图:

在这里插入图片描述
如果我们假设最短路是 A − &gt; B − &gt; C − &gt; E − &gt; F A-&gt;B-&gt;C-&gt;E-&gt;F A>B>C>E>F 3 ⋅ ( ∣ B C ⃗ ∣ + ∣ C E ⃗ ∣ ) &lt; ∣ B D ⃗ ∣ + ∣ D E ⃗ ∣ 3\cdot(|\vec{BC}|+|\vec{CE}|)&lt;|\vec {BD}|+|\vec{DE}| 3(BC +CE )<BD +DE ,那么次短路就是 A − &gt; B − &gt; D − &gt; E − &gt; F A-&gt;B-&gt;D-&gt;E-&gt;F A>B>D>E>F
假设且一开始更新了 A − &gt; B − &gt; C − &gt; E − &gt; F A-&gt;B-&gt;C-&gt;E-&gt;F A>B>C>E>F,那么对于 E E E点而言,我们的次短路就不能通过 C C C D D D点的最短路来更新,而是用 D D D点的次短路更新。
改了一下之前的代码~~(原来的太丑)~~ 。

代码:

#include<cstdio>
#include<cstring>
#include<queue>
#define LL long long
using namespace std;
queue <int> f; 
	struct node{int x,y,next;LL z;} a[300010];
	bool bz[10010];
	int last[10010];
	LL dis1[10010],dis2[10010];
	int n,m,len=0;
void ins(int x,int y,LL z)
{
	a[++len]=(node){x,y,last[x],z}; last[x]=len;
}
void PUSH(int x)
{
	if(bz[x]) bz[x]=false,f.push(x);
}
void spfa()
{
	memset(bz,true,sizeof(bz));
	memset(dis1,63,sizeof(dis1));
	memset(dis2,63,sizeof(dis2));
	dis1[1]=0;
	bz[1]=false;
	f.push(1);
	while(!f.empty())
	{
		int x=f.front();
		for(int i=last[x];i;i=a[i].next)
		{
			int y=a[i].y;
			if(dis1[x]+a[i].z<dis1[y])
			{
				if(dis2[y]>dis1[y]) dis2[y]=dis1[y];
				dis1[y]=dis1[x]+a[i].z;
				PUSH(y);
			}
			if(dis1[x]+a[i].z>dis1[y]&&dis1[x]+a[i].z<dis2[y]) dis2[y]=dis1[x]+a[i].z,PUSH(y);
			if(dis2[x]+a[i].z<dis2[y]) dis2[y]=dis2[x]+a[i].z,PUSH(y);
		}
		bz[x]=true;
		f.pop();
	}
}
int main()
{
	int x,y;
	LL z;
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d %d %lld",&x,&y,&z);
		ins(x,y,z),ins(y,x,z);
	}
	spfa();
	printf("%lld",dis2[n]<(1ll<<60)?dis2[n]:-1);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值