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
| #include <iostream> #include <cstdio> #include <cstring>
using namespace std;
const int MAXN = 250 + 10;
const int INF = 0x3f3f3f3f;
int N, M; int a[MAXN]= {0}, d[MAXN][MAXN]= {0};
int f[MAXN][MAXN], g[MAXN][MAXN]; bool visit[2][MAXN][MAXN]= {false}; struct node { int val, x, y; node (int val = 0, int x = 0, int y = 0) : val (val), x (x), y (y) {} } ; node maxf[MAXN], maxg[MAXN]; void getm (node& a, node b) { if (b.val < a.val) a = b; } void workf (int j) { maxf[j] = node (INF, 0, 0); for (int i = 1; i <= N; i ++) if (! visit[0][i][j]) getm (maxf[j], node (f[i][j], i, j)); } void workg (int j) { maxg[j] = node (INF, 0, 0); for (int i = 1; i <= N; i ++) if (! visit[1][i][j]) getm (maxg[j], node (g[i][j], i, j)); }
inline int getnum () { int num = 0; char ch = getchar (); while (! isdigit (ch)) ch = getchar (); while (isdigit (ch)) num = (num << 3) + (num << 1) + ch - '0', ch = getchar (); return num; }
int main () { memset (d, INF, sizeof (d)); memset (f, INF, sizeof (f)); memset (g, INF, sizeof (g)); N = getnum (), M = getnum (); for (int i = 1; i <= N; i ++) { a[i] = getnum (); d[i][i] = a[i]; } for (int i = 1; i <= M; i ++) { int u = getnum (), v = getnum (); d[u][v] = a[u] + a[v]; } for (int k = 1; k <= N; k ++) for (int i = 1; i <= N; i ++) for (int j = 1; j <= N; j ++) d[i][j] = min (d[i][j], d[i][k] + d[k][j] - a[k]); if (d[1][N] >= INF || d[N][1] >= INF) { puts ("-1"); return 0; } f[1][1] = a[1]; for (int i = 1; i <= N; i ++) workf (i), workg (i); while (true) { node mf, mg; mf = mg = node (INF, 0, 0); for (int i = 1; i <= N; i ++) getm (mf, maxf[i]), getm (mg, maxg[i]); int type = mf.val <= mg.val ? 0 : 1; getm (mf, mg); if (mf.val >= INF) break; int x = mf.x, y = mf.y; if (type) { visit[1][x][y] = true; for (int k = 1; k <= N; k ++) if (k != y) f[k][x] = min (f[k][x], g[x][y] + d[x][k] + d[k][y] - a[x] - a[y] - a[k]); workf (x), workg (y); } else { visit[0][x][y] = true; for (int k = 1; k <= N; k ++) g[k][y] = min (g[k][y], f[x][y] + d[x][k] - a[x]); workf (y), workg (y); } } cout << f[N][N] << endl;
return 0; }
|