时限卡的非常紧,做尽常数优化才过。。
#include <cstdio> #include <cstring> #include <cmath> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #include <list> #include <set> #include <queue> #include <stack> #include <algorithm> using namespace std; typedef long long LL; const int maxn = 505; const int maxm = maxn * maxn; const LL INF = 1e14; struct Edge { int u,v; LL w; bool operator < (const Edge &x) const { return w < x.w; } }; LL dist[maxn][maxn],cow_cnt[maxn],sj_cnt[maxn],cow_sum; LL cap[maxm],v[maxm],maxedge; Edge e[maxm]; int first[maxn],nxt[maxm]; int n,m,s,t,ecnt,oecnt; void adde(int uu,int vv,LL ww) { v[ecnt] = vv; cap[ecnt] = ww; nxt[ecnt] = first[uu]; first[uu] = ecnt++; v[ecnt] = uu; cap[ecnt] = 0; nxt[ecnt] = first[vv]; first[vv] = ecnt++; } void floyd() { maxedge = -1; for(int k = 1;k <= n;k++) { for(int i = 1;i <= n;i++) { for(int j = 1;j <= n;j++) { dist[i][j] = min(dist[i][k] + dist[k][j],dist[i][j]); } } } oecnt = 0; for(int i = 1;i <= n;i++) { for(int j = 1;j <= n;j++) { if(dist[i][j] != INF) { maxedge = max(maxedge,dist[i][j]); e[oecnt].u = i; e[oecnt].v = j; e[oecnt].w = dist[i][j]; oecnt++; } } e[oecnt].u = i; e[oecnt].v = i; e[oecnt].w = 0; oecnt++; } sort(e,e + oecnt); } void input() { memset(first,-1,sizeof(first)); memset(nxt,-1,sizeof(nxt)); s = 0; t = (n << 1) | 1; cow_sum = 0; for(int i = 1;i <= n;i++) { for(int j = 1;j <= n;j++) { dist[i][j] = INF; } } for(int i = 1;i <= n;i++) { scanf("%lld%lld",&cow_cnt[i],&sj_cnt[i]); cow_sum += cow_cnt[i]; } for(int i = 1;i <= m;i++) { int u,v; LL w; scanf("%d%d%lld",&u,&v,&w); dist[u][v] = dist[v][u] = min(dist[u][v],w); } floyd(); } void build_graph(LL minval) { memset(first,-1,sizeof(first)); ecnt = 0; for(int i = 1;i <= n;i++) { adde(i + n,t,sj_cnt[i]); adde(s,i,cow_cnt[i]); } for(int i = 0;i < oecnt;i++) { if(e[i].w > minval) break; adde(e[i].u,e[i].v + n,INF); } } int q[maxn * 2],qs,qe,level[maxn]; bool bfs() { memset(level,0,sizeof(level)); qs = 0; qe = 1; q[qs] = s; level[s] = 1; while(qs < qe) { int now = q[qs++]; for(int i = first[now];i != -1;i = nxt[i]) { if(level[v[i]] == 0 && cap[i] != 0) { q[qe++] = v[i]; level[v[i]] = level[now] + 1; } } } return level[t]; } LL dinic(int now,LL alpha) { if(now == t) return alpha; LL sum = 0; for(int i = first[now];i != -1 && sum < alpha;i = nxt[i]) { if(cap[i] && level[v[i]] == level[now] + 1) { LL ret = dinic(v[i],min(alpha,cap[i])); alpha -= ret; sum += ret; cap[i] -= ret; cap[i ^ 1] += ret; } } if(sum == 0) level[now] = -1; return sum; } bool ok(LL val) { LL ans = 0; build_graph(val); while(bfs()) ans += dinic(s,INF); return ans >= cow_sum; } void solve() { LL l = 1,r = maxedge,ans = -1,mid; while(l <= r) { mid = (l + r) >> 1; if(ok(mid)) { r = mid - 1; ans = mid; } else l = mid + 1; } printf("%lld ",ans); } int main() { while(~scanf("%d%d",&n,&m)) { input(); solve(); } return 0; }