最短路总结
<h1>最短路总结以及最短路衍生问题</h1>
zhw说总结想写就写...
先贴个模板
void Dijkstra()
{
memset(dist, 0x3f, sizeof dist);
dist[1];
p.push({0, 1});
st.reset(); // bitset
while (!p.empty())
{
int ver = p.top().u;
p.pop();
if (st[ver]) continue;
st[ver] = true;
for (int i = head[ver]; i; i = ne[i])
{
int v = to[i], w = we[i];
if (dist[v] > dist[ver] + w)
{
dist[v] > dist[ver] + w
p.push({dist[v], v});
}
}
}
while (!p.empty())
{
int ver = p.top().u;
p.pop();
if (st[ver]) continue;
st[ver] = true;
for (int i = head[ver]; i; i = ne[i])
{
int v = to[i], w = we[i];
if (dist[v] > dist[ver] + w)
{
dist[v] > dist[ver] + w
p.push({dist[v], v});
}
}
}
}
多起点单终点问题(往返)
这种题为最短路的简单变形,处理方法就是建反图:各边全部反向,权值不变。然后从唯一的终点出发即可。
P1629 邮递员送信 该题为纯模板。
P1821 [USACO07FEB] Cow Party S 接近模板题。
多重权值的最短路类问题
该类问题就是在单权值的模板上的变形(单源最短路仅一个权值)。我们通常会对这些权值有一个排序,例如第一、第二关键字等。而这种问题的处理也是非常的简单,仅仅修改上文模板的更新操作即可。
若第二重权值记为
if (dist[v] > dist[u] + w)
{
dist[v] = dist[u] + w;
p.push({dist[v], v});
}
else if (dist[v] == dist[u] + w && ...)
{
// do sth.
p.push({dist[v], v});
}
P3115 [USACO15JAN]Cow Routing S 模板题:费用为第一关键字,坐的飞机数为第二关键字。这道题其实还可以当分层图做。
这里还拿另一种题目与这一类做区分。
P1462 通往奥格瑞玛的道路 该问题不属于这一类:因为它的第二关键字权值是合法性而非最优性要求,因而不可直接放入状态。该题正解为二分。
边太多的单源单权值问题
减小边的数量的方法各异,这里举几个例子:
P3831 [SHOI2012]回家的路 直接建边边数太多,但是我们发现很多站点是交叉不换乘的(没用的),也就是说:只要这个点不是终点我们就不会下车,那这时就可以忽略这些节点,只连接换乘站即可。同时注意换乘站、起点与终点有多个方向可以到达与出发。
与拓扑的结合的最短路问题
由于拓扑排序的性质:是一种统计DAG(有向无环图)中性质的一种算法,通常用于路径计数、图上
-
统计路径。
-
满足某些条件的最短路问题。
最短路计数问题
我们在进行单源最短路过程中,通常只统计了最短路径长度,但是没有考虑最短路径是什么,以及最短路的计数问题。
如果只是单纯的求解最短路径是什么,我们可以考虑在最短路更新操作里加上这么一步:
pre[v]=u;
因为执行该步操作后,我们给每个被更新的到节点一个更新的来源:从
但是通常最短路径不止一条,而且我们也不只是满足于遍历一个路径,我们要求求出所有的最短路径条数。这个就是和拓扑排序相结合。
P1144 最短路计数 这道题为最短路计数问题的模板题。建立最短路图,然后拓扑排序即可。
咕咕咕.....
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】