• POJ 3281 简单构图+最大流


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

    题目大意:

      John有n头牛,每头牛需要分配food和drink,food有F种,drink有D种,每种food和drink最多仅可以被分配一次,每头牛最多可以分配到一种food和一种drink,且每头牛有自己喜欢的food和drink,问最多有多少牛可以得到所期望的分配。

    分析:

      建立一个超级源点ST,ST向F个food分别连一条容量为1的边,表示每种food最多可以使用一次;

      建立一个超级汇点ED,D个drink向ED分别连一条容量为1的边,表示每种drink最多可以使用一次;

      根据牛的喜好,把牛和food,drink连一条容量为1的边;

      考虑到每头牛最多可以被分配到一种food和一种drink,进行拆点,代表牛的点拆成两个点,且这两个点连一条容量为1的边,就限制了牛被分配到的food和drink最多分别有1种。

      具体见代码。

      然后用Edmonds_karp模版一次最大流即可。

    代码:

    poj3281
     1 /*3281    Accepted    904K    79MS    C++    1930B    2012-06-09 13:07:23*/
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <iostream>
     6 #include <algorithm>
     7 #include <vector>
     8 using namespace std;
     9 
    10 #define mpair make_pair
    11 #define pii pair<int,int>
    12 #define MM(a,b) memset(a,b,sizeof(a));
    13 typedef long long lld;
    14 typedef unsigned long long u64;
    15 template<class T> bool up_max(T& a,const T& b){return b>a? a=b,1 : 0;}
    16 template<class T> bool up_min(T& a,const T& b){return b<a? a=b,1 : 0;}
    17 #define maxn 420
    18 
    19 int ST,ED;
    20 int F,N,D;
    21 int g[maxn][maxn];
    22 
    23 void Init(){
    24     ST=0;
    25     ED= F+N+N+D+1;
    26     int i,tf,td,t;
    27     MM( g, 0 );
    28     for(i=1;i<=F;++i) g[0][i]= 1;
    29     for(i=F+1;i<=F+N;++i) g[i][i+N]= 1;
    30     for(i=F+N+N+1;i<=F+N+N+D;++i) g[i][ED]= 1;
    31     for(i=F+1;i<=F+N;++i){
    32         scanf("%d%d", &tf, &td);
    33         while( tf-- ){
    34             scanf("%d", &t);
    35             g[t][i]= 1;
    36         }
    37         while( td-- ){
    38             scanf("%d", &t);
    39             g[i+N][F+N+N+t]= 1;
    40         }
    41     }
    42 }
    43 
    44 const int inf= 2100000000;
    45 bool vis[maxn];
    46 int pre[maxn], que[maxn];
    47 bool bfs(){
    48     fill( vis+ST, vis+ED+1, 0 );
    49     int head= 0, tail= 0;
    50     que[tail++]= ST;
    51     vis[ST]= 1;
    52     while( head<tail ){
    53         int u= que[head++];
    54         for(int v= ST;v<=ED;++v){
    55             if( g[u][v]>0 && !vis[v] ){
    56                 pre[v]= u;
    57                 if( v==ED ) return 1;
    58                 vis[v]= 1;
    59                 que[tail++]= v;
    60             }
    61         }
    62     }
    63     return 0;
    64 }
    65 
    66 int Edmonds_karp(){
    67     int ret= 0;
    68     while( bfs() ){
    69         int t= inf;
    70         for(int i=ED;i!=ST;i=pre[i])
    71             up_min( t, g[pre[i]][i] );
    72         ret+= t;
    73         for(int i=ED;i!=ST;i=pre[i])
    74             g[pre[i]][i]-= t, g[i][pre[i]]+= t;
    75     }
    76     return ret;
    77 }
    78 
    79 int main()
    80 {
    81     //freopen("poj3281.in","r",stdin);
    82     while( cin>>N>>F>>D ){
    83         Init();
    84         int ans= Edmonds_karp();
    85         cout<< ans <<endl;
    86     }
    87 }
  • 相关阅读:
    【转】TCP协议的无消息边界问题
    【转】Log4net用法
    【转】微信公众账号 Senparc.Weixin.MP SDK 开发教程 索引
    关于Asp.Net MVC 中 UpdateModel 的未能更新***模型的 解决方案!
    批准加强军队信息安全工作意见
    iOS--开发从入门到精通
    iOS-开发者账号与证书
    iOS--高级技术
    iOS-----App闪退,程序崩溃---解决方案
    iOS-运行时机制
  • 原文地址:https://www.cnblogs.com/yimao/p/2543030.html
Copyright © 2020-2023  润新知