输入格式: 输入第一行是三个正整数 N、M 和 K,表示魔都地铁有 N 个车站 (1 ≤ N ≤ 200),M 条线路 (1 ≤ M ≤ 1500),最短距离每超过 K 公里 (1 ≤ K ≤ 106),加 1 元车费。 接下来 M 行,每行由以下格式组成: <站点1><空格><距离><空格><站点2><空格><距离><空格><站点3> ... <站点X-1><空格><距离><空格><站点X> 其中站点是一个 1 到 N 的编号;两个站点编号之间的距离指两个站在该线路上的距离。两站之间距离是一个不大于 106 的正整数。一条线路上的站点互不相同。 注意:两个站之间可能有多条直接连接的线路,且距离不一定相等。 再接下来有一个正整数 Q (1 ≤ Q ≤ 200),表示森森尝试从 Q 个站点出发。 最后有 Q 行,每行一个正整数 **Xi**,表示森森尝试从编号为 Xi 的站点出发。 输出格式: 对于森森每个尝试的站点,输出一行若干个整数,表示能够到达的站点编号。站点编号从小到大排序。c语言代码
时间: 2024-02-25 14:57:28 浏览: 100
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXN 205
#define MAXM 1505
#define INF 10000000
int N, M, K, Q;
int dist[MAXN][MAXN]; // dist[i][j]表示i到j的最短距离
int fare[MAXN][MAXN]; // fare[i][j]表示i到j的车费
int ans[MAXN]; // 存储每个起点能到达的站点编号
int min(int a, int b) {
return a < b ? a : b;
}
void floyd() {
for (int k = 1; k <= N; k++) {
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
if (i == j) continue;
if (dist[i][k] != INF && dist[k][j] != INF) {
if (dist[i][j] > dist[i][k] + dist[k][j]) {
dist[i][j] = dist[i][k] + dist[k][j];
fare[i][j] = fare[i][k] + fare[k][j];
} else if (dist[i][j] == dist[i][k] + dist[k][j]) {
fare[i][j] = min(fare[i][j], fare[i][k] + fare[k][j]);
}
}
}
}
}
}
int main() {
scanf("%d%d%d", &N, &M, &K);
memset(dist, INF, sizeof(dist));
memset(fare, INF, sizeof(fare));
for (int i = 1; i <= N; i++) {
dist[i][i] = 0;
fare[i][i] = 0;
}
for (int i = 1; i <= M; i++) {
int cnt, u, v, d;
scanf("%d%d", &cnt, &u);
for (int j = 2; j <= cnt; j++) {
scanf("%d%d", &d, &v);
dist[u][v] = dist[v][u] = d;
fare[u][v] = fare[v][u] = (d - 1) / K + 1;
u = v;
}
}
floyd();
scanf("%d", &Q);
for (int i = 1; i <= Q; i++) {
int x;
scanf("%d", &x);
int cnt = 0;
for (int j = 1; j <= N; j++) {
if (dist[x][j] != INF) {
ans[cnt++] = j;
}
}
printf("%d", ans[0]);
for (int j = 1; j < cnt; j++) {
printf(" %d", ans[j]);
}
printf("\n");
}
return 0;
}
```
阅读全文