写一个C++代码 给定一个 n 个点 m 条边的不含重边和自环的无向图。 点的编号为 1∼n ,边的编号为 1∼m 。 在 t=0 时刻,你位于 1 号点。 你的任务是尽可能早的抵达 n 号点。 第 i 条边连接点 ai 和点 bi ,通过此边需要花费的时间为 ci 。 在整个移动过程中,你只有在整数时刻才能离开某一点前往另一点。 此外,第 i 个点有 ki 个禁止离开时刻。 在每个点的禁止离开时刻,你无法离开该点前往其它点。 请你计算抵达 n 号点的最早可能时刻。
时间: 2023-04-08 15:00:52 浏览: 84
C++无向图深度优先和广度优先遍历(编译可运行).rar
5星 · 资源好评率100%
抱歉,我可以回答这个问题。以下是 C 代码实现:
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
const int MAXN = 100010;
const int INF = 0x3f3f3f3f;
struct Edge {
int to, w;
};
vector<Edge> G[MAXN];
int n, m, k[MAXN];
int d[MAXN], vis[MAXN];
void dijkstra() {
memset(d, INF, sizeof(d));
memset(vis, 0, sizeof(vis));
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
d[1] = 0;
q.push(make_pair(0, 1));
while (!q.empty()) {
int u = q.top().second;
q.pop();
if (vis[u]) continue;
vis[u] = 1;
for (int i = 0; i < G[u].size(); i++) {
int v = G[u][i].to;
int w = G[u][i].w;
if (vis[v]) continue;
int t = d[u] + w;
if (t % 2 == 1 && k[v] == t) t++;
if (t < d[v]) {
d[v] = t;
q.push(make_pair(d[v], v));
}
}
}
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%d", &k[i]);
}
for (int i = 1; i <= m; i++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
G[u].push_back((Edge){v, w});
G[v].push_back((Edge){u, w});
}
dijkstra();
printf("%d\n", d[n]);
return 0;
}
该代码使用 Dijkstra 算法求解最短路,其中需要注意的是,如果当前时间为奇数且等于某个点的禁止离开时刻,需要将时间加一,以保证能够离开该点。
阅读全文