P8802 [蓝桥杯 2022 国 B] 出差 题解
Strelizia_Qy · · 题解
Dijkstra 堆优化 + vector 存图
看到各位 dalao 都用链式前向星,奈何我不会,所以写一篇用 vector 存的。
思路:
注意到是单源最短路,且没有负边权,选择 Dijkstra。
隔离的时间可以丢进路线的时间里,具体操作如下:
每条路的边权=原来的边权+目的地的点权。
这样就转化成了一个 Dijkstra 板子题。
(温馨提示:因为目的地不需要隔离,所以输出时减去城市 N 的隔离时间)
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define pii pair<int,int>
const int maxn=1e5+5,inf=0x3f3f3f3f;
int n,m,add[maxn],dis[maxn];
bool vis[maxn]={0};
vector<pii> G[maxn];
void dijkstra()//Dijkstra
{
for(int i=1;i<=n;i++) dis[i]=inf,vis[i]=0;
dis[1]=0;
priority_queue<pii,vector<pii>,greater<pii> >p;//堆优化
p.push({0,1});
while(!p.empty())
{
int u=p.top().second;
p.pop();
if(vis[u]) continue;
vis[u]=1;
for(int i=0;i<G[u].size();i++)
{
int cost=G[u][i].second,v=G[u][i].first;
if(dis[v]>dis[u]+cost)
{
dis[v]=dis[u]+cost;
p.push({dis[v],v});
}
}
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>add[i];
for(int i=1;i<=m;i++)
{
int a,b,len;
cin>>a>>b>>len;
G[a].push_back({b,len+add[b]});
G[b].push_back({a,len+add[a]});
//vector存图,加上目的地点权
}
dijkstra();
cout<<dis[n]-add[n];//终点不用隔离
}