POJ-3281 Dining(最大流)

原创 2016年05月31日 16:59:48


设容量为1,流量为0的边为edge.
用0表示源点,从零到每个食物之间连上edge,在从食物到相应的牛上连上edge,再从第i个牛到第i个牛上连上edge,在从牛到饮料上连上edge,从饮料到汇点连上edge.
食物标记:1-f;
第一次n头牛f+1, f+n;
第二次n头牛f+n+1, f+2*n;
饮料:f+2*n+1, f+2*n+d;
汇点:f+2*n+d+1;

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <stack>
#include <queue> 
#define maxn 605 
#define INF 1e9
typedef long long ll;

using namespace std;
struct Edge{
    Edge(){
    }
    Edge(int a, int b, int c, int d){
        from = a;
        to = b;
        cap = c;
        flow = d;
    }
    int from, to, cap, flow;
};
vector<Edge> edge;
vector<int> v[maxn];
int p[maxn], a[maxn], n, f, d;
void Addedge(int from, int to){

    edge.push_back(Edge(from, to, 1, 0));
    edge.push_back(Edge(to, from, 0, 0));
    int dd = edge.size();
    v[from].push_back(dd-2);
    v[to].push_back(dd-1);
}
void Init(){

    edge.clear();
    for(int i = 0; i < maxn; i++)
     v[i].clear(); 
    for(int i = 1; i <= n; i++){
        int k1, k2, a;
        scanf("%d%d", &k1, &k2);
        for(int j = 1; j <= k1; j++){
            scanf("%d", &a);
            Addedge(a, i+f);
        }
        for(int j = 1; j <= k2; j++){
            scanf("%d", &a);
            Addedge(f+n+i, f+2*n+a);
        }
    }
    for(int i = 1; i <= f; i++){
        Addedge(0, i);
    }
    for(int i = 1; i <= d; i++){
        Addedge(f+2*n+i, f+2*n+d+1);
    }
    for(int i = 1; i <= n; i++){
        Addedge(i+f, i+f+n);
    }
}
int MaxFlow(){

    int e = f + 2 * n + d + 1;
    int ans = 0;
    while(1){

        memset(a, 0, sizeof(a));
        a[0] = INF;
        queue<int> q;
        q.push(0);
        while(!q.empty()){

            int k = q.front();
            q.pop();
            for(int i = 0; i < v[k].size(); i++){
                Edge &e = edge[v[k][i]];
                if(a[e.to] == 0 && e.cap > e.flow){
                    a[e.to] = min(a[k], e.cap - e.flow);
                    q.push(e.to);
                    p[e.to] = v[k][i];
                }
            }
        }
        if(a[e] == 0)
          break;
        ans += a[e];
        for(int i = e; i != 0; i = edge[p[i]].from){
            edge[p[i]].flow += 1;
            edge[p[i]^1].flow -= 1;
        }
    }
    return ans;
}
int main(){

//  freopen("in.txt", "r", stdin);
    while(scanf("%d%d%d",&n, &f, &d) == 3){
        Init();
        cout << MaxFlow() << endl;
    }
    return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

poj 3281 Dining(分点,最大流)

Dining Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 14136   Accept...
  • acm_cxq
  • acm_cxq
  • 2016年06月02日 19:36
  • 210

【最大流模板题】POJ 3281 Dining

题目链接:http://poj.org/problem?id=3281 题目大意:给定N头牛、F个食物、D个饮料。每头牛有一定的喜好,只喜欢其中几个食物和饮料。每个食物和饮料只能给一头牛即一头牛只能得...

POJ3281--Dining(最大流)

主要是构图。 刚开始我想的是源点->牛->食物->饮料,发现问题很多,正确的构图应该是源点->食物->牛->牛->饮料->汇点,中间牛与牛之间的容量为1。 #include #include #i...

POJ3281 Dining (拆点+最大流)

题意: N头牛,准备了F种食物,D种饮料,每一头牛会喜欢若干种食物和饮料,但它只能选择一种食物和一种饮料,且每种食物和饮料都只够一头牛选择,问怎样分配能使得食物和饮料都能得到的牛的数量最多,求这个数。...

POJ3281 Dining [最大流应用]

2012/2/25 更新。 题意: 每只牛有他喜欢的食物和饮料,问怎样匹配可以使能吃到满意的食物和饮料的牛的数量最大。 思路: 匹配问题。最大流的应用。难点在构图。 我对最大流的理解就是:应...
  • wuyanyi
  • wuyanyi
  • 2011年09月06日 22:05
  • 348

poj3281 Dining(最大流)

题意:n头牛,f种食物,d种饮料,每头牛对应若干食物和饮料,要给每一头牛分配一种饮料喝一种食物,互不重复。求最多几头牛可以分配到。 建图,边的权值均为1。源点向食物建边,饮料向汇点建边,每个牛建两个结...

【网络流-最大流-Dinic-建模】POJ3281 Dining:Pascal 解法

传送门:POJ3281 【题目大意】 有N头奶牛,每一头都有自己喜欢的食物和饮料,且它们只吃自己喜欢的东西。每头牛只能选一个食物与一个饮料现在有F种食物,D种饮料,求最多能够同时满足几头奶牛的需求...

POJ 3281Dining(网络流之最大流)

题目地址:

poj 3281 Dining(网络流最大流+分点)

题目大意:有N种食物,和N种饮料.每头牛有喜欢的饮料和食物.问有多少头牛可以同时吃到自己喜欢的饮料和食物. 思路:这道题主要在于建图问题. 添加超级汇点和超级源点自然不用多说了. 正确的建模:源...

poj 3281 Dining 【图论-网络流-最大流-EK&Ford-Fulkerson】

Dining Time Limit: 2000MS Memory Limit: 65536K Description Cows are such f...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:POJ-3281 Dining(最大流)
举报原因:
原因补充:

(最多只允许输入30个字)