用C++写这道题的代码:给定一个 n 个点 m 条边的不含重边和自环的无向图。 点的编号为 1∼n ,边的编号为 1∼m 。 在 t=0 时刻,你位于 1 号点。 你的任务是尽可能早的抵达 n 号点。 第 i 条边连接点 ai 和点 bi ,通过此边需要花费的时间为 ci 。 在整个移动过程中,你只有在整数时刻才能离开某一点前往另一点。 此外,第 i 个点有 ki 个禁止离开时刻。 在每个点的禁止离开时刻,你无法离开该点前往其它点。 请你计算抵达 n 号点的最早可能时刻。
时间: 2023-04-08 17:00:54 浏览: 89
C++无向图深度优先和广度优先遍历(编译可运行).rar
5星 · 资源好评率100%
抱歉,我可以回答这个问题。以下是用C语言写这道题的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXN 100005
#define MAXM 200005
#define INF 0x3f3f3f3f
typedef struct {
int v, w, next;
} Edge;
Edge edge[MAXM];
int head[MAXN], cnt;
int n, m, k[MAXN];
int dis[MAXN], vis[MAXN];
void addEdge(int u, int v, int w) {
edge[++cnt].v = v;
edge[cnt].w = w;
edge[cnt].next = head[u];
head[u] = cnt;
}
void dijkstra() {
memset(dis, INF, sizeof(dis));
memset(vis, 0, sizeof(vis));
dis[1] = 0;
for (int i = 1; i <= n; i++) {
int u = 0;
for (int j = 1; j <= n; j++) {
if (!vis[j] && (u == 0 || dis[j] < dis[u])) {
u = j;
}
}
vis[u] = 1;
for (int j = head[u]; j; j = edge[j].next) {
int v = edge[j].v, w = edge[j].w;
if (!vis[v] && dis[u] % w == 0 && dis[u] / w + 1 < k[v]) {
dis[v] = dis[u] + w;
}
}
}
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
addEdge(u, v, w);
addEdge(v, u, w);
}
for (int i = 1; i <= n; i++) {
scanf("%d", &k[i]);
}
dijkstra();
printf("%d\n", dis[n]);
return 0;
}
```
这是一个基于 Dijkstra 算法的解法,时间复杂度为 O(n^2)。在每次选取最短路的时候,我们需要枚举所有未访问的点,找到距离起点最近的那个点。然后,我们遍历以该点为起点的所有边,更新与该点相邻的点的最短路。在更新的时候,我们需要判断当前时刻是否可以离开该点,以及是否可以在下一个整数时刻到达相邻的点。如果可以,我们就更新最短路。最终,我们得到的最短路就是抵达 n 号点的最早可能时刻。
阅读全文