先预处理出来每个点对之间的最短距离

然后二分答案,网络流判断是否可行就好了恩

 

  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\n", 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 }
View Code

 

posted on 2015-04-30 22:53  Xs酱~  阅读(257)  评论(0编辑  收藏  举报