题目描述
题目出处:点这里
输入格式
输出格式
样例
输入
4 4
5 7 3 4
1 2 4
1 3 5
2 4 3
3 4 5
输出
13
提示
样例说明
样例规模
分析与思路
观察数据的范围不难发现,运用Dijkstra算法就可以轻松解决
但是同时,这个题目在边权上加入了“隔离时间”,导致我们不仅要计算两城市之间路程所花费的时间,还要多计算到达这座城市后的“隔离时间”
那么我们应如何解决这个问题呢?
思路一
进行简单的预处理,我们构建一个以各城市为顶点,城市之间的通路为边,两座城市之间路程的时间为边权的图,然后将隔离时间加在边权上,最后用Dijkstra算法求解即可
注意
这是一个无向图,在将隔离时间加到边权上时,一定要想清楚:究竟要加上两座城市中哪一座城市的隔离时间(必须加上终点城市的隔离时间才可以获得正确结果)
思路二
与思路一类似,只不过是将隔离时间与路程时间分开存储,使用Dijkstra算法求解,进行松弛操作的时候,加上隔离时间
代码实现
此代码实现的是思路二
#include<bits/stdc++.h>
using namespace std;
const int MXV=0x3f3f3f3f;
const int MXN=1e4+5;
bool flag[MXN+1];
int dist[MXN+1];//记录路程时间
int gltime[MXN+1];//记录隔离时间
int bi[MXN+1][MXN+1];
int n,m,c,u,v,w;
vector<int>edges[MXN+1];
struct Node{
int id,dist;
Node(){}
Node(int i,int d){
id=i;dist=d;
}
friend bool operator < (Node a,Node b){
return a.dist>b.dist;
}
};
priority_queue<Node>pque;
void Dijkstra(int sid){
memset(dist,0x3f,sizeof(dist));
dist[sid]=0;
pque.push(Node(sid,dist[sid]));
while(pque.size()){
Node from=pque.top();pque.pop();
if(flag[from.id])continue;
flag[from.id]=true;
for(auto to:edges[from.id]){
//进行松弛操作时加上隔离时间
if(dist[to]>bi[from.id][to]+from.dist+gltime[to]){
dist[to]=bi[from.id][to]+from.dist+gltime[to];
pque.push(Node(to,dist[to]));
}
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&c);
gltime[i]=c;
}
for(int i=1;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
edges[u].push_back(v);
edges[v].push_back(u);
bi[u][v]=bi[v][u]=w;
}
Dijkstra(1);
//输出时要减去起点城市隔离的时间
printf("%d\n",dist[n]-gltime[n]);
return 0;
}