zoukankan      html  css  js  c++  java
  • HDU4292 Food 简单网络流

    依据题中所给定的关系构图,直接网络流。

    源点到食物,食物到人,人拆成两个点,流量为1,再从人到饮料。

    代码如下:

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #define INF 0x3fffffff
    #define F(x) (x)
    #define N(x) (205+(x))
    #define CPN(x) (410+(x))
    #define D(x) (615+(x))
    using namespace std;
    
    int n, f, d, head[1005], dis[1005], idx;
    int que[1000], front, tail;
    
    const int SS = 0, TT = 1000;
    
    struct Edge {
        int v, cap, next;
    }e[200000];
    
    void addedge(int x, int v, int cap) {
        ++idx;
        e[idx].v = v, e[idx].cap = cap;
        e[idx].next = head[x], head[x] = idx;
        ++idx;
        e[idx].v = x, e[idx].cap = 0;
        e[idx].next = head[v], head[v] = idx;    
    }
    
    bool bfs() {
        int pos;
        memset(dis, 0xff, sizeof (dis));
        dis[SS] = front = tail = 0;
        que[++tail] = SS;
        while (front != tail) {
            pos = que[++front];
            for (int i = head[pos]; i != -1; i = e[i].next) {
                if (e[i].cap > 0 && dis[e[i].v] == -1) {
                    dis[e[i].v] = dis[pos] + 1;
                    if (e[i].v == TT) return true;
                    que[++tail] = e[i].v;
                }    
            }
        }
        return false;
    }
    
    int dfs(int u, int flow) {
        if (u == TT) {
            return flow;    
        }
        int f, tf = 0;
        for (int i = head[u]; i != -1; i = e[i].next) {
            if (dis[u]+1 == dis[e[i].v] && e[i].cap > 0 && (f = dfs(e[i].v, min(e[i].cap, flow - tf)))) {
                e[i].cap -= f;
                e[i^1].cap += f;
                tf += f;
                if (tf == flow) return flow;
            }
         }
         if (!tf) dis[u] = -1;
         return tf;
    }
    
    int dinic() {
        int ret = 0;
        while (bfs()) {
            ret += dfs(SS, INF);    
        }
        return ret;
    }
    
    int main() {
        int c;
        char like[205];
        while (scanf("%d %d %d", &n, &f, &d) == 3) {
            memset(head, 0xff, sizeof (head));
            idx = -1;
            for (int i = 1; i <= f; ++i) {
                scanf("%d", &c);    
                addedge(SS, F(i), c);
            }
            for (int i = 1; i <= d; ++i) {
                scanf("%d", &c);
                addedge(D(i), TT, c);
            }
            for (int i = 1; i <= n; ++i) {
                addedge(N(i), CPN(i), 1);
                scanf("%s", like+1);
                for (int j = 1; j <= f; ++j) {
                    if (like[j] == 'Y') {
                        addedge(F(j), N(i), 1);    
                    }
                }
            }
            for (int i = 1; i <= n; ++i) {
                scanf("%s", like+1);
                for (int j = 1; j <= d; ++j) {
                    if (like[j] == 'Y') {
                        addedge(CPN(i), D(j), 1);    
                    }    
                }    
            }
            printf("%d\n", dinic());
        }
        return 0;    
    }
  • 相关阅读:
    月食照片
    宾得镜头大全与发展史
    月食照片
    关于镜头系数的疑问
    经验和教训
    常用正则表达式
    12月19日
    部長面談
    周六
    异度空间
  • 原文地址:https://www.cnblogs.com/Lyush/p/2694694.html
Copyright © 2011-2022 走看看