用C++写这道题的代码:给定一个 n 个点 m 条边的不含重边和自环的无向图。 点的编号为 1∼n ,边的编号为 1∼m 。 在 t=0 时刻,你位于 1 号点。 你的任务是尽可能早的抵达 n 号点。 第 i 条边连接点 ai 和点 bi ,通过此边需要花费的时间为 ci 。 在整个移动过程中,你只有在整数时刻才能离开某一点前往另一点。 此外,第 i 个点有 ki 个禁止离开时刻。 在每个点的禁止离开时刻,你无法离开该点前往其它点。 请你计算抵达 n 号点的最早可能时刻。
时间: 2023-04-08 10:00:53 浏览: 64
抱歉,我可以回答这个问题。这是一个最短路问题,可以使用 Dijkstra 算法或者 Bellman-Ford 算法来解决。在算法中,需要考虑每个点的禁止离开时刻,可以将每个点的禁止离开时刻看作一个虚拟的点,然后将其与原图中的点连接起来,边权为0,表示在该时刻可以到达该点。然后再对新图进行最短路计算即可。
相关问题
写一个C++代码 给定一个 n 个点 m 条边的不含重边和自环的无向图。 点的编号为 1∼n ,边的编号为 1∼m 。 在 t=0 时刻,你位于 1 号点。 你的任务是尽可能早的抵达 n 号点。 第 i 条边连接点 ai 和点 bi ,通过此边需要花费的时间为 ci 。 在整个移动过程中,你只有在整数时刻才能离开某一点前往另一点。 此外,第 i 个点有 ki 个禁止离开时刻。 在每个点的禁止离开时刻,你无法离开该点前往其它点。 请你计算抵达 n 号点的最早可能时刻。
抱歉,我可以回答这个问题。以下是 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 算法求解最短路,其中需要注意的是,如果当前时间为奇数且等于某个点的禁止离开时刻,需要将时间加一,以保证能够离开该点。
c++实现 7-2 单源最短路径 请编写程序求给定正权有向图的单源最短路径长度。图中包含n个顶点,编号为0至n-1,以顶点0作为源点。 输入格式: 输入第一行为两个正整数n和e,分别表示图的顶点数和边数,其中n不超过20000,e不超过1000。接下来e行表示每条边的信息,每行为3个非负整数a、b、c,其中a和b表示该边的端点编号,c表示权值。各边并非按端点编号顺序排列。 输出格式: 输出为一行整数,为按顶点编号顺序排列的源点0到各顶点的最短路径长度(不含源点到源点),每个整数后一个空格。如源点到某顶点无最短路径,则不输出该条路径长度。 输入样例: 4 4 0 1 1 0 3 1 1 3 1 2 0 1 输出样例: 1 1 代码长度
下面是使用Dijkstra算法求解单源最短路径的C++代码实现,时间复杂度为O(ElogV):
```c++
#include <iostream>
#include <vector>
#include <queue>
#include <limits.h>
using namespace std;
const int INF = INT_MAX;
int main() {
int n, e;
cin >> n >> e;
vector<vector<pair<int, int>>> graph(n);
for (int i = 0; i < e; i++) {
int a, b, c;
cin >> a >> b >> c;
graph[a].push_back({b, c});
}
vector<int> dist(n, INF);
dist[0] = 0;
vector<bool> visited(n, false);
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
pq.push({0, 0});
while (!pq.empty()) {
int d = pq.top().first;
int u = pq.top().second;
pq.pop();
if (visited[u]) {
continue;
}
visited[u] = true;
for (auto p : graph[u]) {
int v = p.first;
int w = p.second;
if (dist[u] + w < dist[v]) {
dist[v] = dist[u] + w;
pq.push({dist[v], v});
}
}
}
for (int i = 1; i < n; i++) {
if (dist[i] == INF) {
cout << -1 << " ";
} else {
cout << dist[i] << " ";
}
}
return 0;
}
```
其中,dist数组表示源点0到各个顶点的最短路径长度,visited数组表示该顶点是否已经被访问过。pq优先队列用于维护一个小根堆,每次取出堆顶的元素表示到某个顶点的最短路径已经确定。在更新每个顶点的最短路径时,如果发现新的路径比原来的路径更短,则更新dist数组并将该顶点加入小根堆中。
阅读全文