zoukankan      html  css  js  c++  java
  • H

    题目大意:有N个人,然后有F种食品和D种饮料,每个人都有喜欢的饮料和食品,求出来这些食品最多能满足多少人的需求。

    输入描述:

     

    分析:以前是做过类似的题目的,不过输入的信息量比较大,还是使用邻接表的好些,邻接矩阵有可能会TLE,建图如下图流程

    不过要注意人需要拆点的,因为一个人只食用一种食品就可以了,所以拆点让他们之间的流量为1。ps:很伤心的这题竟然做了6个小时,算是比较裸的最大流题目....最后终于检查出来错误的位置,dinic里面把while循环写成了if,貌似这是第二次犯这么二缺的事儿了。
    下面是AC代码。
    ==========================================================================================================
    #include<stdio.h>
    #include<algorithm>
    #include<queue>
    #include<string.h>
    using namespace std;

    const int MAXN = 1005;
    const int oo = 1e9+7;

    struct Edge{int v, flow, next;}edge[MAXN*MAXN];
    int Head[MAXN], cnt;
    int layer[MAXN];///分层

    void InIt()
    {
        cnt = 0;
        memset(Head, -1sizeof(Head));
    }
    void AddEdge(int u, int v, int flow)
    {
        edge[cnt].v = v;
        edge[cnt].flow = flow;
        edge[cnt].next = Head[u];
        Head[u] = cnt++;
    }
    bool bfs(int start, int End)
    {
        queue<int> Q;Q.push(start);
        memset(layer, 0sizeof(layer));
        layer[start] = 1;

        while(Q.size())
        {
            int u = Q.front();Q.pop();

            if(u == End)return true;

            for(int j=Head[u]; j!=-1; j=edge[j].next)
            {
                int v = edge[j].v;

                if(layer[v] == false && edge[j].flow)
                {
                    layer[v] = layer[u] + 1;
                    Q.push(v);
                }
            }
        }

        return false;
    }
    int dfs(int u, int MaxFlow, int End)
    {
        if(u == End)return MaxFlow;

        int uflow = 0;

        for(int j=Head[u]; j!=-1; j=edge[j].next)
        {
            int v = edge[j].v;

            if(layer[v]==layer[u]+1 && edge[j].flow)
            {
                int flow = min(MaxFlow-uflow, edge[j].flow);
                flow = dfs(v, flow, End);

                edge[j].flow -= flow;
                edge[j^1].flow += flow;
                uflow += flow;

                if(uflow == MaxFlow)break;
            }
        }

        if(uflow == 0)
            layer[u] = 0;
        return uflow;
    }
    int dinic(int start, int End)
    {
        int MaxFlow = 0;

        while(bfs(start, End) == true)
            MaxFlow += dfs(start, oo, End);

        return MaxFlow;
    }

    int main()
    {
        int N, F, D;

        while(scanf("%d%d%d", &N, &F, &D) != EOF)
        {///把人拆成两个中间流量是1
            int Fi=N*2, Di=Fi+F, start=Di+D+1, End=start+1;
            int i, j, x; char s[MAXN]={0};

            InIt();

            for(i=1; i<=F; i++)
            {///食物与源点相连
                scanf("%d", &x);
                AddEdge(start, Fi+i, x);
                AddEdge(Fi+i, start, 0);
            }

            for(i=1; i<=D; i++)
            {///饮料与汇点相连
                scanf("%d", &x);
                AddEdge(Di+i, End, x);
                AddEdge(End, Di+i, 0);
            }

            for(i=1; i<=N; i++)
            {///每个人对每种食物的喜欢或者不喜欢
                scanf("%s", s+1);
                for(j=1; s[j]; j++)
                {
                    if(s[j] == 'Y')
                    {///建立食物和人的关系
                        AddEdge(Fi+j, i, 1);
                        AddEdge(i, Fi+j, 0);
                    }
                }

                ///人拆成两个点
                AddEdge(i, N+i, 1);
                AddEdge(N+i, i, 0);
            }
            for(i=1; i<=N; i++)
            {///个人对饮料的喜爱
                scanf("%s", s+1);
                for(j=1; s[j]; j++)
                {///建立饮料和人(拆点)的关系
                    if(s[j] == 'Y')
                    {
                        AddEdge(N+i, Di+j, 1);
                        AddEdge(Di+j, N+i, 0);
                    }
                }
            }

            printf("%d ", dinic(start, End));
        }

        return 0;

    }

  • 相关阅读:
    PHP操作redis
    鼠标失去焦点处理办法
    关于HTTP协议,一篇就够了
    什么是 CDN(超形象)
    网站部署之~阿里云系列汇总
    阿里云系列——6.给你的域名使用CDN加速(详细步骤+简单配置)
    mysql备份与还原
    .NET框架之“小马过河”
    .NET使用Bogus生成大量随机数据
    .NET中的值类型与引用类型
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4719111.html
Copyright © 2011-2022 走看看