万里之行,始于足下。本博客总结暑期学习到的图论模板第二部分,以便于日后查询使用。作者水平有限,难免存在疏漏不足,恳请诸位看官斧正。倘若我的文章可以帮到你,十分荣幸。感谢18级学长ljh提供的灵感。本篇博客可能篇幅较长,主要讲最短路的求法。
目录
1.Label-Setting算法
这里我们着重介绍Dijkstra算法。问题描述:给定有向加权图G(V, E),给定起始点s,求从s出发到其它所有顶点的权重(正整数)最小的路径。存在重边时,只保留最短的1条。
1.Dijkstra算法的三个模块
1.寻找不在最短路径树的点中,离源点最近的点。
2.将这个点标记,即放入最短路径树中。
3.更新最短路径树所连点到源点的距离。
2.基础Dijkstra算法的代码实现
如题:洛谷-P3371 【模板】单源最短路径(弱化版)上代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct edge
{
ll to,w;
edge(ll t,ll wi):to(t),w(wi){};
};//结构体存边
const ll inf=2147483647,len=5e5+5;
vector<edge> v[len];//存图
ll n,m,s;
ll dis[len],vis[len];//各点到原点的最短路径和是否在最短路径树中
//以下为算法核心部分
void dijkstra(ll s)
{
for(int i=1;i<=n;i++)
{
dis[i]=inf;
}//初始化为正无穷
memset(vis,0,sizeof(vis));//初始化最短路径树
dis[s]=0;
ll turn=n;
while(turn--)
{
ll minDis=inf,target=-1;
for(int i=1;i<=n;i++)
{
if(!vis[i]&&dis[i]<minDis)
{
target = i;
minDis = dis[i];
}
}//Findmin
vis[target]=1;//合并target到最短路径树中
for(ll i=0;i<v[target].size();i++)
{
ll t=v[target][i].to;//target指向的点
dis[t]=min(dis[t],v[target][i].w+dis[target]);
}//Update
}
}
//以上为算法核心部分
int main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n>>m>>