zoukankan      html  css  js  c++  java
  • HDU-4292 Food(最大流,拆点)

    题目链接:HDU-4292 Food

    题意

    有$N$个人、$F$种食物、$D$种饮料,每种食物和饮料有一定数量,每个人对每种食物和饮料有数量为1的需求或无需求,问这$F$种食物和$D$种饮料最多能满足多少个人的需求。


    思路

    一个人拆成两个结点,分为左部点和右部点,左部点向右部点连容量为1的边,表示一个人对答案的贡献最多为1;

    源点向代表食物的结点连边,容量为对应的食物的数量,食物向对这种食物有需求的人的左部点连边,容量为1,表示需求为1;

    人的右部点向有需求的饮料连边,容量为1,表示对这种饮料需求为1,饮料向汇点连边,容量为对应的饮料的数量,然后跑最大流即可。


    代码实现

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    using std::queue;
    const int INF = 0x3f3f3f3f, N = 1000, M = 200000;
    int head[N], d[N];
    int s, t, tot, maxflow;
    struct Edge
    {
        int to, cap, nex;
    } edge[M];
    queue<int> q;
    void add(int x, int y, int z) {
        edge[++tot].to = y, edge[tot].cap = z, edge[tot].nex = head[x], head[x] = tot;
        edge[++tot].to = x, edge[tot].cap = 0, edge[tot].nex = head[y], head[y] = tot;
    }
    bool bfs() {
        memset(d, 0, sizeof(d));
        while (q.size()) q.pop();
        q.push(s); d[s] = 1;
        while (q.size()) {
            int x = q.front(); q.pop();
            for (int i = head[x]; i; i = edge[i].nex) {
                int v = edge[i].to;
                if (edge[i].cap && !d[v]) {
                    q.push(v);
                    d[v] = d[x] + 1;
                    if (v == t) return true;
                }
            }
        }
        return false;
    }
    int dinic(int x, int flow) {
        if (x == t) return flow;
        int rest = flow, k;
        for (int i = head[x]; i && rest; i = edge[i].nex) {
            int v = edge[i].to;
            if (edge[i].cap && d[v] == d[x] + 1) {
                k = dinic(v, std::min(rest, edge[i].cap));
                if (!k) d[v] = 0;
                edge[i].cap -= k;
                edge[i^1].cap += k;
                rest -= k;
            }
        }
        return flow - rest;
    }
    void init(int v_num) {
        tot = 1, maxflow = 0;
        s = v_num, t = s + 1;
        memset(head, 0, sizeof(head));
    }
    
    int main() {
        int nn, nf, nd;
        while (~scanf("%d %d %d", &nn, &nf, &nd)) {
            init(nn * 2 + nf + nd);
            for (int i = 0, num; i < nf; i++) {
                scanf("%d", &num);
                add(s, i, num);
            }
            for (int i = 0, num; i < nd; i++) {
                scanf("%d", &num);
                add(i + nf, t, num);
            }
            char str[210];
            for (int i = 0; i < nn; i++) {
                scanf(" %s", str);
                for (int j = 0; j < nf; j++) {
                    if (str[j] == 'Y') add(j, i + nf + nd, 1);
                }
                add(nf + nd + i, nf + nd + nn + i, 1);
            }
            for (int i = 0; i < nn; i++) {
                scanf(" %s", str);
                for (int j = 0; j < nd; j++) {
                    if (str[j] == 'Y') add(nn + nf + nd + i, nf + j, 1);
                }
            }
            while (bfs()) maxflow += dinic(s, INF);
            printf("%d
    ", maxflow);
        }
        return 0;
    }
    View Code
    作者:_kangkang
    本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    leetcode-594-Longest Harmonious Subsequence
    leetcode-581-Shortest Unsorted Continuous Subarray
    leetcode-575-Distribute Candies(计算一个数组中元素的种类的快速方法)
    leetcode-566-Reshape the Matrix
    leetcode-561-Array Partition I
    leetcode-551-Student Attendance Record I(判断是否出现连续几个相同字符)
    Java之CheckedException
    Java异常机制
    Zookeeper分布式协调即分布式锁机制
    Spring中@Value用法
  • 原文地址:https://www.cnblogs.com/kangkang-/p/11331842.html
Copyright © 2011-2022 走看看