(单源最短路)[USACO11DEC]RoadBlock S

博客详细分析了USACO竞赛中关于单源最短路问题的解决方案。首先,通过朴素方法讨论了先求最短路再枚举扩大边的过程,接着优化策略,证明扩大边权必为原最短路边,并使用pre数组记录。文章重点解决了在链式前向星中处理边权扩大和避免后续运行中死循环的问题,通过邻接矩阵存储边的位置以及在Dijkstra算法中增加参数来标记首次运行。
摘要由CSDN通过智能技术生成

一、算法分析

首先想朴素的方法,存图,先跑一遍最短路,然后枚举扩大二倍的边,然后再跑最短路。然后优化,易证扩大的边必然是原最短路的边,所以要记录原最短路的边,记录方式是写一个pre数组,这样从后往前扫一遍就行了。但是注意两个难点,一是如何在链式前向星中扩大边权,我采用的方式是,用邻接矩阵来存某两个点a到b的边在前向星数组中的w的编号。二是要注意,只有第一次跑单源最短路的时候,要记录pre数组,之后的都不能改pre数组了,否则可能会发生死循环,我采用的解决方法是给dijkstra函数加一个参数用来标记是否是第一次跑即可。

二、代码及注释

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<queue>
#define x first
#define y second
using namespace std;
typedef pair<int,int> PII;
const int inf=0x3f3f3f3f;
const int N=150;
const int M=10050;
//加倍的路必然在最短路上
int G[N][N];                                                              
int dist[N];
int st[N];
int n,m;
int pre[N];
int h[N],e[M]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值