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 }
  • 相关阅读:
    javaweb常识
    分页功能的实现
    登录按钮的美化
    如何将数据库中的值经过servlet传入到jsp页面,并且用EL表达式显示出值
    获取当前系统时间添加到对象中
    导航栏/菜单栏的设置
    验证码的设计与记住我存储用户名密码cookie的技术及单选按钮选择登录人身份的实现
    div悬浮窗口设计来完成注册页面
    jdbc封装的类
    ajax验证用户名是否存在
  • 原文地址:https://www.cnblogs.com/huangxf/p/4299878.html
Copyright © 2011-2022 走看看