题目链接:蓝桥杯2022年第十三届决赛真题-出差 - C语言网
思路分析:这个题在思路上要注意:1.我们如何看待在每个城市需要隔离的时间,这里我用的是单独开辟的数组,其实也可以在创建邻接图时就将再下一个所到达的城市需要隔离的时间算在从起点到这条路的花费上,需要注意,开始的第一个点和最后的N城市不需要花费隔离时间,这一部分在计算时应该减去,剩下的就是普通的单元最短路径算法了。
还有,特别提醒,注意memset一般我们只是初始化数组为0或-1,初始化为其他值可能会导致错误,我调试半天才调出来,我也是现在才知道这个事......
那么下面就看代码吧:
#include <iostream>
#include <cstring>
#define maxm 1205
using namespace std;
int g[maxm][maxm], d[maxm];
int t[maxm],vis[maxm];
int n, m;
int ans = 0;
void dfs(int i)
{
for (int j = 1; j <= n; j++)
{
d[j] = g[i][j]+t[j];
}
vis[i] = 1;
d[i] = 0;
int k = 0;
while (k < n)
{
int x = -1;
int min =maxm;
for (int j = 1; j <= n; j++)
{
if (vis[j]==0 && d[j] < min)
{
x = j;
min = d[j];
}
}
//按题意来说不可能存在走不通的情况
if (x == -1)
break;
vis[x] = 1;
//cout << "下一步要走"<<x << endl;
//再来更新因为加入新的点之后而更新了最小值的其他点
for (int j = 1; j <= n; j++)
{
if (vis[j]==0 && d[j] >d[x] + g[x][j] + t[j])
d[j] = d[x] + g[x][j] + t[j];
/*
这个地方一定要注意,一开始我就写成了d[j] >g[i][j]+t[x] + g[x][j] + t[j],之所以不对,是因为我们的起点不可能一直是i,所以我们的d[j]需要根据上一个状态进行比较更新,不能与一个确定的目标进行对比
*/
}
k++;//最后别忘了++
}
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> t[i];
}
t[1] = 0;
t[n] = 0;
memset(vis, 0, sizeof(vis));//注意memset只能初始化数组为0或-1,否则就会初始化为随机值,重要的事情只讲一遍
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
{
g[i][j] = maxm;
}
for (int i = 1; i <= n; i++)
d[i] = maxm;
for (int i = 0; i < m; i++)
{
int tx, ty, time;
cin >> tx >> ty >> time;
g[tx][ty] = g[ty][tx] = time;
}
dfs(1);
cout <<d[n] << endl;
/*for (int i = 2; i < n; i++)
{
cout << "到达" << i << "城市的最短用时为" << d[i] - t[i] << endl;
}*/
return 0;
}
如果你努力了,但是事情并没有多大的改变,并不能证明你没有用,而是代表你在赎罪,你总得为你过去的懒散付出点代价,这个时候你应该更加努力而不是消沉下去,欠的账总会还完,日子总会阳光明媚的,很多人看似输掉的是结果,而本质上输掉的是过程,人生没有白走的路,也没有白读的书,好运都是努力的伏笔,哪怕乌云密布,继续攀爬就是晴空万里,所以,请继续努力。
------《人民日报》