次短路径问题

一、问题描述

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;
}

posted @   ltign  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示