zoukankan      html  css  js  c++  java
  • poj 3281 Dining 最大流

    题目链接:http://poj.org/problem?id=3281

    Cows are such finicky eaters. Each cow has a preference for certain foods and drinks, and she will consume no others.

    Farmer John has cooked fabulous meals for his cows, but he forgot to check his menu against their preferences. Although he might not be able to stuff everybody, he wants to give a complete meal of both food and drink to as many cows as possible.

    Farmer John has cooked F (1 ≤ F ≤ 100) types of foods and prepared D (1 ≤ D ≤ 100) types of drinks. Each of his N (1 ≤ N ≤ 100) cows has decided whether she is willing to eat a particular food or drink a particular drink. Farmer John must assign a food type and a drink type to each cow to maximize the number of cows who get both.

    Each dish or drink can only be consumed by one cow (i.e., once food type 2 is assigned to a cow, no other cow can be assigned food type 2).

    题目描述:有F种食物和D种饮料(1<=F<=100,1<=D<=100)、n头牛(1<=n<=100),每头牛有自己喜欢的一些食物和饮料。现在每头牛只能吃一种喜欢的食物和喝一种喜欢的饮料,一种食物和饮料也只能提供给一头牛。问最多能有多少头牛可以吃到食物喝到饮料。

    算法分析:我们知道供应的资源不止一种,需求方只有牛这一个群体,所以我们可以把牛这一群体放在中间,两边是供应的资源,形成源点-食物-牛-饮料-汇点的有向边。 对每头牛 i 这个节点拆成 i 和 i+n 两个点,新增源点from和汇点to,源点到每一种食物连边,权值为1(因为每种食物只能提供给一头牛),每一种饮料到汇点连边,权值为1。接下来就是食物-牛-饮料的关系了:对牛喜欢的食物j连边 j->i ,喜欢的饮料k连边 i+n->k ,权值均为1。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cstdlib>
      5 #include<cmath>
      6 #include<algorithm>
      7 #include<queue>
      8 #define inf 0x7fffffff
      9 using namespace std;
     10 const int maxn=1000+10;
     11 
     12 int n,F,D;
     13 struct node
     14 {
     15     int u,flow;
     16     int next;
     17 }edge[maxn*5];
     18 int head[maxn*5],edgenum;
     19 int from,to;
     20 int d[maxn*5];
     21 
     22 void add(int u,int v,int flow)
     23 {
     24     edge[edgenum].u=v ;edge[edgenum].flow=flow ;
     25     edge[edgenum].next=head[u];
     26     head[u]=edgenum++;
     27 
     28     edge[edgenum].u=u ;edge[edgenum].flow=0;
     29     edge[edgenum].next=head[v];
     30     head[v]=edgenum++;
     31 }
     32 
     33 int bfs()
     34 {
     35     memset(d,0,sizeof(d));
     36     d[from]=1;
     37     queue<int> Q;
     38     Q.push(from);
     39     while (!Q.empty())
     40     {
     41         int u=Q.front() ;Q.pop() ;
     42         for (int i=head[u] ;i!=-1 ;i=edge[i].next)
     43         {
     44             int v=edge[i].u;
     45             if (!d[v] && edge[i].flow>0)
     46             {
     47                 d[v]=d[u]+1;
     48                 Q.push(v);
     49                 if (v==to) return 1;
     50             }
     51         }
     52     }
     53     return 0;
     54 }
     55 
     56 int dfs(int u,int flow)
     57 {
     58     if (u==to || flow==0) return flow;
     59     int cap=flow;
     60     for (int i=head[u] ;i!=-1 ;i=edge[i].next)
     61     {
     62         int v=edge[i].u;
     63         if (d[v]==d[u]+1 && edge[i].flow>0)
     64         {
     65             int x=dfs(v,min(cap,edge[i].flow));
     66             edge[i].flow -= x;
     67             edge[i^1 ].flow += x;
     68             cap -= x;
     69             if (cap==0) return flow;
     70         }
     71     }
     72     return flow-cap;
     73 }
     74 
     75 int dinic()
     76 {
     77     int sum=0;
     78     while (bfs()) sum += dfs(from,inf);
     79     return sum;
     80 }
     81 
     82 int main()
     83 {
     84     while (scanf("%d%d%d",&n,&F,&D)!=EOF)
     85     {
     86         memset(head,-1,sizeof(head));
     87         edgenum=0;
     88         from=2*n+F+D+1;
     89         to=from+1;
     90         int f,d,a;
     91         for (int i=2*n+1 ;i<=2*n+F ;i++)
     92             add(from,i,1);
     93         for (int i=2*n+F+1 ;i<=2*n+F+D ;i++)
     94             add(i,to,1);
     95         for (int i=1 ;i<=n ;i++)
     96         {
     97             scanf("%d%d",&f,&d);
     98             while (f--)
     99             {
    100                 scanf("%d",&a);
    101                 add(2*n+a,i,1);
    102             }
    103             while (d--)
    104             {
    105                 scanf("%d",&a);
    106                 add(i+n,2*n+F+a,1);
    107             }
    108             add(i,i+n,1);
    109         }
    110         printf("%d
    ",dinic());
    111     }
    112     return 0;
    113 }
  • 相关阅读:
    OSGI企业应用开发(八)整合Spring和Mybatis框架(一)
    error C2998:不能是模板定义的错误解决
    <Android 应用 之路> 干货集中营 ~ GankIOClient
    OSGI企业应用开发(七)细说Blueprint & Gemini Blueprint(二)
    C语言初学者代码中的常见错误与瑕疵(15)
    C语言初学者代码中的常见错误与瑕疵(14)
    C语言初学者代码中的常见错误与瑕疵(13)
    《C语言入门很简单》欢乐槽点
    为什么在我眼里你是一只傻逼——傻逼“常所用”句型之(2)——“当当网的就有XXX人评论,YYY%的推荐”
    踢爆IT劣书出版黑幕——由清华大学出版社之《C语言入门很简单》想到的(3)
  • 原文地址:https://www.cnblogs.com/huangxf/p/4299878.html
Copyright © 2011-2022 走看看