1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| #include <cstdio> #include <queue> #include <cstring> #define gc (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 131072, stdin), p1 == p2) ? EOF : *p1 ++) inline int min(int x, int y) {return x < y ? x : y;}
char buf[131072], *p1 = buf, *p2 = buf; inline int read() { char ch; int x(0); while ((ch = gc) < 48); while (ch >= 48) x = x * 10 + ch - 48, ch = gc; return x; }
struct Edge { int to, v, nxt; } e[200005];
int dis[22][20001], dp[1 << 21][22], head[20001], prep[22], tot, K, n, m, t; bool vis[22][20001], flag[1 << 21][22], mp[22][22], In[22]; std::queue<int> q;
inline void AddEdge(int u, int v, int w) { e[++ tot].to = v, e[tot].nxt = head[u], e[tot].v = w, head[u] = tot; }
inline int SPFA(int st) { q.push(st); int *Dis = dis[st]; bool *Vis = vis[st]; memset(dis[st], 0x3f, sizeof(dis[st])); Dis[st] = 0; while (q.size()) { int u(q.front()); q.pop(); Vis[u] = 0; for (int i(head[u]); i; i = e[i].nxt) { int v(e[i].to); if (Dis[u] + e[i].v < Dis[v]) { Dis[v] = Dis[u] + e[i].v; if (!Vis[v]) q.push(v), Vis[v] = 1; } } } }
inline void dfs(int u, int before) { prep[u] |= before; for (int i(2); i <= K; ++ i) if (mp[u][i]) dfs(i, before | 1 << u - 1); }
inline int DP() { memset(dp, 0x3f, sizeof(dp)); dp[1][1] = 0; for (int i(2); i < 1 << K; ++ i) for (int j(0); j < K; ++ j) if (i & 1 << j) { int t(i ^ 1 << j); if ((prep[j + 1] | t) > t) continue; for (int k(0); k < K; ++ k) if (t & 1 << k) dp[i][j] = min(dp[i][j], dp[t][k] + dis[k + 1][j + 1]); } int ans(0x3fffffff); for (int j(0); j < K; ++ j) ans = min(ans, dp[(1 << K) - 1][j] + dis[j + 1][n]); return ans; }
int main() { int n(read()), m(read()); K = read() + 1; while (m --) { int u(read()), v(read()), w(read()); AddEdge(u, v, w), AddEdge(v, u, w); } int t(read()); while (t --) { int u(read()), v(read()); mp[u][v] = 1, In[v] = 1; } for (int i(2); i <= K; ++ i) SPFA(i); for (int i(2); i <= K; ++ i) if (!In[i]) dfs(i, 0); printf("%d", DP()); return 0; }
|