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 }
  • 相关阅读:
    模糊搜索工具fzf的安装和使用
    ubuntu状态栏位置调整
    毕业相关事项
    vimium拓展程序使用技巧
    python文件生成exe可执行文件
    解决pycharm无法识别PyQt4.QtCore的问题
    pyqt4安装以及pycharm下环境配置
    动态规划——最小编辑代价
    深度学习绘图工具
    Maven Spring JUnit 在Maven Clean Install时报
  • 原文地址:https://www.cnblogs.com/huangxf/p/4299878.html
Copyright © 2011-2022 走看看