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 105 106 107 108 109 110 111 112 113
| #include <bits/stdc++.h>
using namespace std;
const int Maxn = 1000 + 10, Maxm = 10000 + 10, inf = 100000000;
int N, M, K; int e, Begin[Maxm], To[Maxm * 2], Next[Maxm * 2], W[Maxm * 2]; int Dis[Maxn][(1 << 11)], Vis[Maxm], Dp[(1 << 11)];
inline void Init () { e = 0; memset(Begin, 0, sizeof Begin); memset(Vis, 0, sizeof Vis); for (int i = 1; i <= N + M; ++i) for (int j = 0; j < (1 << 10); ++j) Dis[i][j] = inf; }
inline void add_edge (int x, int y, int z) { To[++e] = y; Next[e] = Begin[x]; Begin[x] = e; W[e] = z; }
queue <int> Q; inline void SPFA (int state) { while (!Q.empty()) { int x = Q.front(); Q.pop(); Vis[x] = 0; for (int i = Begin[x]; i; i = Next[i]) { int y = To[i]; if (Dis[y][state] > Dis[x][state] + W[i]) { Dis[y][state] = Dis[x][state] + W[i]; if (!Vis[y]) { Vis[y] = 1; Q.push(y); } } } } }
int main() { #ifdef hk_cnyali freopen("A.in", "r", stdin); freopen("A.out", "w", stdout); #endif while (~scanf("%d%d%d", &N, &M, &K)) { Init(); for (int i = 1; i <= N + M; ++i) { int x; scanf("%d", &x); if (i <= N) { Dis[i][(1 << (i - 1))] = 0; Dis[i][(1 << (i - 1)) | (1 << N)] = x; } else Dis[i][1 << N] = x; } while (K--) { int x, y, z; scanf("%d%d%d", &x, &y, &z); add_edge(x, y, z); add_edge(y, x, z); }
int tmp = N + 1; for (int state = 1; state < (1 << tmp); ++state) { for (int i = 1; i <= N + M; ++i) { for (int s1 = state & (state - 1); s1; s1 = state & (s1 - 1)) Dis[i][state] = min(Dis[i][state], Dis[i][(state - s1)] + Dis[i][s1]); if (Dis[i][state] != inf) Q.push(i), Vis[i] = 1; } SPFA(state); }
for (int state = 1; state < (1 << tmp); ++state) { Dp[state] = inf; for (int i = 1; i <= N + M; ++i) Dp[state] = min(Dp[state], Dis[i][state]);
}
for (int state = 1; state < (1 << tmp); ++state) { if (!(state & (1 << N))) continue; for (int s1 = state & (state - 1); s1; s1 = state & (s1 - 1)) { if (!(s1 & (1 << N))) continue; Dp[state] = min(Dp[state], Dp[s1] + Dp[(state - s1) | (1 << N)]); } } cout<<Dp[(1 << tmp) - 1]<<endl; } return 0; }
|