有向圖中從 1 到 N 的最短路。每條邊有額外屬性:若走這條邊前已到達過節點 c,則花費減為 P,否則為原價。求最小花費,不可達輸出 impossible。
struct Edge { int from, to, c, dis1, dis2; };
struct State { int u, mask, d; bool operator<(const State& o) const { return d > o.d; } };
int dp[15][1 << 10];
bool vis[15][1 << 10];
vector edges;
void dijkstra() {
memset(dp, 0x3f, sizeof(dp));
memset(vis, 0, sizeof(vis));
priority_queue pq;
dp[1][1 << 0] = 0;
pq.push({1, 1 << 0, 0});
while (!pq.empty()) {
State cur = pq.top(); pq.pop();
if (vis[cur.u][cur.mask]) continue;
vis[cur.u][cur.mask] = true;
for (auto& e : edges) if (e.from == cur.u) {
int nmask = cur.mask | (1 << (e.to - 1));
int cost = (cur.mask & (1 << (e.c - 1))) ? e.dis2 : e.dis1;
if (dp[e.to][nmask] > cur.d + cost) {
dp[e.to][nmask] = cur.d + cost;
pq.push({e.to, nmask, dp[e.to][nmask]});
}
}
}
}
由於只關心節點 1 到 N 的最短路,終止條件可優化:當彈出節點 N 時即可結束(但需注意不同 mask 可能更新答案,建議跑全圖取 min)。