题目大意:给出N个点,M条线,Q个询问,问从起点到终点,最多经过k个点的最短线路
解题思路:spfa直接跑,然后纪录最短路的数组加一个维度,纪录经过几个点就可以了,还是挺水的
#include <cstdio>
#include <cstring>
#include <map>
#include <iostream>
#include <queue>
using namespace std;
#define N 110
#define M 1010
#define INF 0x3f3f3f3f
struct Edge{
int u, v, next, c;
}E[M];
struct Node {
int u, time;
Node() {}
Node(int u, int time): u(u), time(time) {}
}n1, n2;
map<string, int> city;
int n, m, tot, q;
int head[N], d[N][N];
bool vis[N][N];
void AddEdge(int u, int v, int c) {
E[tot].v = v;
E[tot].c = c;
E[tot].next = head[u];
head[u] = tot++;
}
void init() {
city.clear();
scanf("%d", &n);
string a, b;
for (int i = 1; i <= n; i++) {
cin >> a;
city[a] = i;
}
memset(head, -1, sizeof(head));
tot = 0;
scanf("%d", &m);
int c;
for (int i = 0; i < m; i++) {
cin >> a >> b >> c;
AddEdge(city[a], city[b], c);
}
}
int s, t;
void spfa() {
memset(d, 0x3f, sizeof(d));
memset(vis, 0, sizeof(vis));
queue<Node> Q;
Q.push(Node(s,0));
d[s][0] = 0;
while (!Q.empty()) {
n1 = Q.front();
Q.pop();
int u = n1.u, time = n1.time;
for (int i = head[n1.u]; ~i; i = E[i].next) {
int v = E[i].v;
if (d[u][time] + E[i].c < d[v][time + 1]) {
d[v][time + 1] = d[u][time] + E[i].c;
if (!vis[v][time + 1]) {
vis[v][time + 1] = true;
Q.push(Node(v, time + 1));
}
}
}
}
}
void solve() {
s = city["Calgary"]; t = city["Fredericton"];
spfa();
scanf("%d", &q);
int Max;
while (q--) {
scanf("%d", &Max);
Max = min(Max, n);
int ans = INF;
for (int i = 0; i <= Max + 1; i++)
ans = min(ans, d[t][i]);
if (ans == INF)
printf("No satisfactory flights\n");
else
printf("Total cost of flight(s) is $%d\n", ans);
}
}
int main() {
int test, cas = 1;
bool flag = false;
scanf("%d", &test);
while (test--) {
if (flag)
printf("\n");
flag = true;
printf("Scenario #%d\n", cas++);
init();
solve();
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-10 10:59:23