zoukankan      html  css  js  c++  java
  • POJ 3281 Dining

    题目大意:

    有N只牛,每只牛都偏爱吃一种食和饮料,现在有F种食物,D种饮料,现在想要给尽可能多的牛一份美餐。
     
    输入数据:
    一个N代表N只牛, F代表有F种食物, D代表有D种饮料。
    接下来N行,
    第i行代表,第i只牛,每行前两个数,Fi, Di 分别代表第i只牛喜欢的食物有Fi种,喜欢的饮料有Di种。
    然后是Fi个数字,和Di个数字。
    ===========================================================================================
    把牛拆开,  使得牛与牛之间的流量为 1, 虚拟一个源点 虚拟一个汇点。
     
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    using namespace std;
    typedef long long LL;
    const int INF = 1e9+7;
    const int maxn = 5005;
    const int MOD = 1e9+7;
    int n, F, D, k;
    int Layer[maxn], Head[maxn];
    struct Edge
    {
        int from, to, flow;
        int next;
    } edge[maxn*2];
    
    void AddEdge(int from,int to,int flow)
    {
        edge[k].from = from;
        edge[k].to = to;
        edge[k].flow = flow;
        edge[k].next = Head[from];
        Head[from] = k ++;
    
        swap(from, to);
    
        edge[k].from = from;
        edge[k].to = to;
        edge[k].flow = 0;
        edge[k].next = Head[from];
        Head[from] = k ++;
    }
    
    bool BfsLayer(int Star,int End)
    {
        queue<int> Q;
        memset(Layer, -1, sizeof(Layer));
        Layer[Star] = 1;
        Q.push(Star);
    
        while( Q.size() )
        {
            int s = Q.front(), to;
            Q.pop();
            if(s == End)
                return true;
    
            for(int i=Head[s]; i != -1; i=edge[i].next)
            {
                to = edge[i].to;
                if( Layer[to] == -1 && edge[i].flow)
                {
                    Q.push(to);
                    Layer[to] = Layer[s] + 1;
                }
            }
        }
        return false;
    }
    
    int DFS(int Star,int End,int MaxFlow)
    {
        if(Star == End)///如果已经到达汇点
            return MaxFlow;
    
        int sFlow = 0;///这点到达汇点的流量
        for(int i=Head[Star]; i != -1; i=edge[i].next)
        {
            int to = edge[i].to;
            int flow = edge[i].flow;
    
            if(Layer[Star] + 1 == Layer[to] && flow)
            {
                flow = min(MaxFlow-sFlow, flow);/// (到达Star的最大流量 - 从Star流出的流量,路径上最大限制的流量) = 到达下一个点的最大流量
                flow = DFS(to, End, flow);///返回to可以到达汇点的最大流量
    
                sFlow += flow;
                edge[i].flow -= flow;
                edge[i^1].flow += flow;
    
                if(sFlow == MaxFlow)///改点已经不能再分配出其他流量了。
                    break;
            }
        }
        if(sFlow == 0)///这个点已经不能再向汇点输送流量了。
            Layer[Star] = -1;
    
        return sFlow;
    }
    
    int Dinic(int Star,int End)
    {
        int ans = 0;
        while( BfsLayer(Star, End) )
        {
            ans += DFS(Star, End, INF);
        }
        return ans;
    }
    
    
    int main()
    {
        while(cin >> n >> F >> D)
        {
            int Fi, Di, f, d;
            int N1=F, N2=N1+n, Ds=N2+n, start=Ds+D+1, End=start+1;
    
            k = 0;
            memset(Head, -1, sizeof(Head));
    
            for(int i=1; i<=n; i++)
            {
                cin >> Fi >> Di;
    
                AddEdge(N1+i, N2+i, 1);///把牛拆点建图,建立牛一和牛二之间的联系
    
                for(int j=0; j<Fi; j++)
                {
                    cin >> f;
                    AddEdge(f, N1+i, 1);///建立食物和牛一之间的联系
                }
    
                for(int j=0; j<Di; j++)
                {
                    cin >> d;
                    AddEdge(N2+i, Ds+d, 1);///建立牛二和饮料之间的联系
                }
            }
    
            for(int i=1; i<=F; i++)
                AddEdge(start, i, 1);
            for(int i=1; i<=D; i++)
                AddEdge(Ds+i, End, 1);
    
            printf("%d
    ", Dinic(start, End) );
        }
        return 0;
    }
  • 相关阅读:
    音标,口型,舌位对照表:适合已有一定英语基础的人重新回顾音标发音,在不断的练习中让自己的发音更准确,口型更标准。
    c++友元函数和友元类
    经典MFC界面和Ribbon界面框架对比(单文档为例)
    QEM三维模型简化算法
    VC6和VS2008中C++编译器差异
    VS操作技巧
    msvcrt.lib和LIBCD.lib链接冲突
    二叉树遍历算法
    IE/QQ使用代理上网
    Google Map街景(红蓝立体)
  • 原文地址:https://www.cnblogs.com/chenchengxun/p/4851264.html
Copyright © 2011-2022 走看看