给出一张 \(n\) 个点 \(m\) 条边的有向图。对于每条边 \((a, b)\),如果之前经过 \(c\) 点,那么费用为 \(p\),否则为 \(r\)。求 \(1\) 到 \(n\) 的最小费用。如果无法到达则输出 "impossible"。
其实这是一道最短路的变形,但是由于 \(n\) 的范围很小,可以直接搜索(DFS),而且每条边可以走多次,我们只需加以限制即可。
#include <cstdio> const int MAXN = 15, INF = 1e9; int n, m, ans; int a[MAXN], b[MAXN], c[MAXN], p[MAXN], r[MAXN]; int vis[MAXN]; void dfs(int k, int now) { if (now >= ans) return ; if (k == n) { ans = now; return ; } for (int i = 1; i <= m; i++) { if (a[i] == k) { if (vis[b[i]] >= 3) continue; vis[b[i]]++; if (b[i] == c[i] && vis[b[i]] == 1) dfs(b[i], now + r[i]); else dfs(b[i], now + (vis[c[i]] ? p[i] : r[i])); vis[b[i]]--; } } } int main() { scanf("%d %d", &n, &m); for (int i = 1; i <= m; i++) scanf("%d %d %d %d %d", &a[i], &b[i], &c[i], &p[i], &r[i]); vis[1] = 1; ans = INF; dfs(1, 0); if (ans == INF) return printf("impossible"), 0; printf("%d", ans); return 0; }