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 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
| #include <iostream> #include <queue> #include <cstdio>
using namespace std;
const int maxg = 10; const int maxk = 155; const int maxs = 15; const int maxn = 11; const int maxm = 11; int n, m, p, k, s; int ecnt = 2; int head[maxn * maxm * (1 << maxg)], dis[maxn * maxm * (1 << maxg)]; bool vis[maxn * maxm * (1 << maxg)]; struct edge { int to, next, w; } g[(1 << maxg) * (maxk * 2 * 4 + maxs)]; void add_edge(int u, int v, int w) { g[ecnt] = (edge) { v, head[u], w }; head[u] = ecnt ++; } void add_edge(int x1, int y1, int l1, int x2, int y2, int l2, int w) { add_edge(y1 + (x1 - 1) * m + m * n * l1, y2 + (x2 - 1) * m + m * n * l2, w); } inline int id (int x, int y) { return (x - 1) * m + y ; } int map[200][200];
struct node { int dis, pos; friend bool operator < (const node &a, const node &b) { return a.dis > b.dis; } }; priority_queue<node> q;
void dijkstra() { for (int i = 1; i <= m * n * (1 << p); i ++) dis[i] = 2e9; dis[1] = 0; q.push((node) { dis[1], 1 }); while (!q.empty()) { int u = q.top().pos; q.pop(); if (vis[u]) continue; vis[u] = true; for (int e = head[u]; e; e = g[e].next) { int v = g[e].to; if (dis[v] > dis[u] + g[e].w) { dis[v] = dis[u] + g[e].w; q.push((node) { dis[v], v }); } } } }
int main() { cin >> n >> m >> p >> k; for (int i = 1; i <= k; i ++) { int x1, x2, y1, y2, g; cin >> x1 >> y1 >> x2 >> y2 >> g; if (g == 0) g = -1; map[id(x1, y1)][id(x2, y2)] = g; map[id(x2, y2)][id(x1, y1)] = g; } for (int l = 0; l < (1 << p); l ++) { for (int i = 1; i <= n; i ++) { for (int j = 1; j <= m; j ++) { if (j < m) { int g = map[id(i, j)][id(i, j + 1)]; if (g == 0) { add_edge(i, j, l, i, j + 1, l, 1); add_edge(i, j + 1, l, i, j, l, 1); } if ((l & (1 << (g - 1))) && (g != 0) && (g != -1)) { add_edge(i, j, l, i, j + 1, l, 1); add_edge(i, j + 1, l, i, j, l, 1); } } if (i < n) { int g = map[id(i, j)][id(i + 1, j)]; if (g == 0) { add_edge(i, j, l, i + 1, j, l, 1); add_edge(i + 1, j, l, i, j, l, 1); } if ((l & (1 << (g - 1))) && (g != 0) && (g != -1)) { add_edge(i, j, l, i + 1, j, l, 1); add_edge(i + 1, j, l, i, j, l, 1); } } } } } cin >> s; for (int i = 1; i <= s; i ++) { int x, y, q; cin >> x >> y >> q; for (int l = 0; l < (1 << p); l ++) { if (l & (1 << (q - 1))) continue; add_edge(x, y, l, x, y, (l | (1 << (q - 1))), 0); } } dijkstra(); int ans = 2e9; for (int i = 1; i <= (1 << p); i ++) ans = min(ans, dis[m * n * i]); if (ans == 2e9) ans = -1; cout << ans << endl; return 0; }
|