先预处理出来每个点对之间的最短距离
然后二分答案,网络流判断是否可行就好了恩
1 /************************************************************** 2 Problem: 1738 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:404 ms 7 Memory:9788 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <cstring> 12 #include <algorithm> 13 14 using namespace std; 15 typedef long long ll; 16 const int N = 405; 17 const int M = N * N << 2; 18 const int inf_int = 1e9; 19 const ll inf_ll = (ll) 1e18; 20 21 inline int read(); 22 23 struct edge { 24 int next, to, f; 25 edge(int _n = 0, int _t = 0, int _f = 0) : next(_n), to(_t), f(_f) {} 26 } e[M]; 27 28 int n, m, S, T; 29 int a[N], b[N], sum; 30 ll mp[N][N]; 31 int first[N], tot; 32 int d[N]; 33 34 inline void Add_Edges(int x, int y, int z) { 35 e[++tot] = edge(first[x], y, z), first[x] = tot; 36 e[++tot] = edge(first[y], x), first[y] = tot; 37 } 38 #define y e[x].to 39 #define p q[l] 40 bool bfs() { 41 static int l, r, x, q[N]; 42 memset(d, -1, sizeof(d)); 43 d[q[1] = S] = 1; 44 for (l = r = 1; l != r + 1; ++l) 45 for (x = first[p]; x; x = e[x].next) 46 if (!~d[y] && e[x].f) { 47 d[q[++r] = y] = d[p] + 1; 48 if (y == T) return 1; 49 } 50 return 0; 51 } 52 #undef p 53 54 int dfs(int p, int lim) { 55 if (p == T || !lim) return lim; 56 int x, tmp, rest = lim; 57 for (x = first[p]; x && rest; x = e[x].next) 58 if (d[y] == d[p] + 1 && ((tmp = min(e[x].f, rest)) > 0)) { 59 rest -= (tmp = dfs(y, tmp)); 60 e[x].f -= tmp, e[x ^ 1].f += tmp; 61 if (!rest) return lim; 62 } 63 if (rest) d[p] = -1; 64 return lim - rest; 65 } 66 #undef y 67 68 int Dinic() { 69 int res = 0; 70 while (bfs()) 71 res += dfs(S, inf_int); 72 return res; 73 } 74 75 inline bool check(ll t) { 76 static int i, j; 77 memset(first, 0, sizeof(first)), tot = 1; 78 for (i = 1; i <= n; ++i) 79 Add_Edges(S, i * 2 - 1, a[i]), Add_Edges(i * 2, T, b[i]); 80 for (i = 1 ; i <= n; ++i) 81 for (j = 1; j <= n; ++j) 82 if (mp[i][j] <= t) Add_Edges(i * 2 - 1, j * 2, inf_int); 83 return Dinic() == sum; 84 } 85 86 int main() { 87 int i, j, k, x, y, z; 88 ll l, r, mid; 89 n = read(), m = read(), S = n * 2 + 1, T = S + 1; 90 for (i = 1; i <= n; ++i) 91 sum += (a[i] = read()), b[i] = read(); 92 for (i = 1; i <= n; ++i) 93 for (j = 1; j <= n; ++j) mp[i][j] = i == j ? 0 : inf_ll; 94 for (i = 1; i <= m; ++i) { 95 x = read(), y = read(), z = read(); 96 if (mp[x][y] > z) mp[x][y] = mp[y][x] = z; 97 } 98 for (k = 1; k <= n; ++k) 99 for (i = 1; i <= n; ++i) 100 for (j = 1; j <= n; ++j) 101 mp[i][j] = min(mp[i][j], mp[i][k] + mp[k][j]); 102 103 l = 0, r = inf_ll; 104 while (l + 1 < r) { 105 mid = l + r >> 1; 106 if (check(mid)) r = mid; 107 else l = mid; 108 } 109 printf("%lld ", r == inf_ll ? -1ll : r); 110 return 0; 111 } 112 113 inline int read() { 114 static int x; 115 static char ch; 116 x = 0, ch = getchar(); 117 while (ch < '0' || '9' < ch) 118 ch = getchar(); 119 while ('0' <= ch && ch <= '9') { 120 x = x * 10 + ch - '0'; 121 ch = getchar(); 122 } 123 return x; 124 }