HDU-4292 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;    

}

 

你可能感兴趣的:(HDU)