您的位置:首页 > 产品设计 > UI/UE

BZOJ 1570: [JSOI2008]Blue Mary的旅行( 二分答案 + 最大流 )

2016-02-03 12:40 459 查看


二分答案, 然后对于答案m, 把地点分成m层, 对于边(u, v), 第x层的u -> 第x+1层的v 连边. 然后第x层的u -> 第x+1层的u连边(+oo), S->第一层的1(PEOPLE_NUMBER), 每一层N -> T(+oo), 假如最大流是等于人数,就是可行答案.

----------------------------------------------------------------------------------------

#include<cstdio>#include<cstring>#include<algorithm> using namespace std; #define Id(a, b) ((a) + (b) * N) const int maxn = 59;const int maxV = 5009; int V, S, T, cnt[maxV], h[maxV];int d[maxn][maxn], NUM, N; struct edge { int t, c; edge *n, *r;} E[100000], *pt, *e, *H[maxV], *p[maxV], *cur[maxV]; inline void Add(int u, int v, int c) { pt->t = v, pt->c = c, pt->n = H[u], H[u] = pt++;}inline void AddEdge(int u, int v, int c) { Add(u, v, c), Add(v, u, 0); H[u]->r = H[v], H[v]->r = H[u];} int maxFlow() { for(int i = 0; i < V; i++) cur[i] = H[i], cnt[i] = h[i] = 0; cnt[0] = V; int ret = 0; for(int x = S, A = maxV; h[S] < V; ) { for(e = cur[x]; e; e = e->n) if(e->c && h[e->t] + 1 == h[x]) break; if(e) { A = min(e->c, A); p[e->t] = cur[x] = e; if((x = e->t) == T) { for(; x != S; x = p[x]->r->t) p[x]->c -= A, p[x]->r->c += A; ret += A; A = maxV; } } else { if(!--cnt[h[x]]) break; h[x] = V; for(e = H[x]; e; e = e->n) if(h[e->t] + 1 < h[x] && e->c) { h[x] = h[e->t] + 1; cur[x] = e; } ++cnt[h[x]]; if(x != S) x = p[x]->r->t; } } return ret;} void Build(int x) { pt = E; memset(H, 0, sizeof H); V = N * x, S = V++, T = V++; AddEdge(S, 0, NUM); for(int i = 0; i < x; i++) AddEdge(Id(N - 1, i), T, maxV); for(int i = 1; i < x; i++) for(int j = 0; j < N; j++) { for(int k = 0; k < N; k++) if(d[j][k]) AddEdge(Id(j, i - 1), Id(k, i), d[j][k]); AddEdge(Id(j, i - 1), Id(j, i), maxV); }} void Init() { int m; scanf("%d%d%d", &N, &m, &NUM); memset(d, 0, sizeof d); while(m--) { int u, v; scanf("%d%d", &u, &v); scanf("%d", &d[--u][--v]); }} void Work() { int l = 1, r = 100, ans; while(l <= r) { int m = (l + r) >> 1; Build(m); if(maxFlow() == NUM) { ans = m, r = m - 1; } else l = m + 1; } printf("%d\n", --ans);} int main() { Init(); Work(); return 0;}----------------------------------------------------------------------------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: