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


    二分答案, 然后对于答案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 ", --ans);
    }
     
    int main() {
    Init();
    Work();
    return 0;
    }

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

  • 相关阅读:
    jQuery常用方法一览
    基于jQuery的AJAX和JSON实现纯html数据模板
    jQuery+ASP.NET的AJAX文件上传
    jquery 新建的元素事件绑定问题
    二、visual studio 2008 快捷键
    Sql Server表相关的语句
    使用临时表
    IIS如何启用Gzip压缩功能
    php5.2 的 php.ini 中文版
    joomla笔记——对joomla的初步认识
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/5179446.html
Copyright © 2020-2023  润新知