【题解】洛谷P2865

题目传送门

我们可以用1次dijkstra解决这个问题。

每次读入队首进行更新时有三种情况:

1.更新最短路、次短路。

2.能更新次短路,但不能更新最短路。

3.啥也不能更新。

用dis代表最短路,ldis代表次短路。

q.top().dis+w<dis[v]时可以更新最短路和次短路:

1
2
ldis[v]=dis[v];
dis[v]=q.top().dis+w;

q.top().dis+w>dis[v]&&q.top().dis+w<ldis[v]时可以更新次短路:

1
ldis[v]=q.top().dis+w;

哦,还有判断队首节点是否要继续更新的条件也要改成

1
front.dis>ldis[u]

不然就会跳过更新次短路。

以下是代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include<bits/stdc++.h>
using namespace std;
const int MAXN=5010,inf=0x3f3f3f3f;
struct edge
{
int v,w;
};
vector <edge> g[MAXN];
struct node
{
int u,dis;
bool operator <(const node a)const
{
return dis>a.dis;
}
};
int dis[MAXN],ldis[MAXN],n,m;
priority_queue <node> q;
void dijkstra()
{
memset(dis,inf,sizeof(dis));
memset(ldis,inf,sizeof(ldis));
dis[1]=0;
q.push({1,0});
while(!q.empty())
{
node front=q.top();
q.pop();
int u=front.u;
if(front.dis>ldis[u])continue;
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i].v,w=g[u][i].w;
if(front.dis+w<dis[v])
{
ldis[v]=dis[v];
dis[v]=front.dis+w;
q.push({v,dis[v]});
}
if(front.dis+w>dis[v]&&front.dis+w<ldis[v])
{
ldis[v]=front.dis+w;
q.push({v,ldis[v]});
}
}
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int u,v,w;
cin>>u>>v>>w;
g[u].push_back({v,w});
g[v].push_back({u,w});
}
dijkstra();
cout<<ldis[n];
return 0;
}

【题解】洛谷P2865
http://j27egu.github.io/2025/08/23/【题解】洛谷P2865/
作者
j27eGU
发布于
2025年8月23日
许可协议