次短路径问题
一、问题描述
P2865 [USACO06NOV] Roadblocks G
二、问题简析
如果求最短路径,我们很自然会想到 \(Dijkstra\)。但是,这道题要求的是次短路径。
记到 \(u\) 的最短路径为 \(d_1[u]\),到 \(u\) 的次短路径为 \(d_2[u]\)。则 \(d_2[v] = d_1[u] + e(u, v)\) or \(d_2[u] + e(u, v).w\)。
因此,我们需要求出所有顶点的最短路径和次短路径。我们依然可以采用 \(Dijkstra\),只是多维护一个次短路径数组。
三、代码
#include <bits/stdc++.h>
using namespace std;
#define MAX 10 // 最多顶点数
#define INF 1e8
typedef struct {int to, worth;} edge;
typedef pair<int, int> P;
int n, m; // n -- 顶点数; m -- 边数
vector<edge> G[MAX]; // 邻接表
int d1[MAX], d2[MAX]; // d1 -- 最短路径; d2 -- 次短路径
struct cmp
{
bool operator()(const P &a, const P &b)
{
return a.second > b.second;
}
};
int quickin(void)
{
int ret = 0;
char ch = getchar();
while (ch < '0' || ch > '9')
ch = getchar();
while (ch >= '0' && ch <= '9')
{
ret = 10 * ret + ch - '0';
ch = getchar();
}
return ret;
}
void solve(void)
{
// 初始化
fill(begin(d1), end(d1), INF);
fill(begin(d2), end(d2), INF);
d1[1] = 0; // 只能初始化d1[0],d2[0] > 0未知
priority_queue<P, vector<P>, cmp> Q; // 最小优先队列
Q.push(P(1, 0));
while (!Q.empty())
{
P p = Q.top();
Q.pop();
int u = p.first; // p.second可能是最短路径也可能是次短路径
if (d2[u] < p.second) continue; // u的最短路径和次短路径都能进入下一步
for (int i = 0; i < G[u].size(); i++)
{
edge e = G[u][i];
int dis = p.second + e.worth; // 最短路径 or 次短路径 + e(u, v).w
// 最短路径
if (d1[e.to] > dis)
{
swap(d1[e.to], dis); // 交换后,dis >= d1[e.to]
Q.push(P(e.to, d1[e.to])); // s 到 e.to 的最短路径
}
// 次短路径
if (d2[e.to] > dis && d1[e.to] < dis) // 次短路径必须大于最短路径
{
d2[e.to] = dis;
Q.push(P(e.to, d2[e.to])); // s 到 e.to 的次短路径
}
}
}
printf("%d\n", d2[n]);
}
int main()
{
n = quickin(), m = quickin();
for (int i = 0; i < m; i++)
{
int a, b, c;
a = quickin(), b = quickin(), c = quickin();
G[a].push_back(edge{b, c});
G[b].push_back(edge{a, c});
}
solve();
return 0;
}
完
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具