zoukankan      html  css  js  c++  java
  • poj 3281 Dining (最大网络流)

    题目链接:

      http://poj.org/problem?id=3281

    题目大意:

      有n头牛,f种食物,d种饮料,第i头牛喜欢fi种食物和di种饮料,每种食物或者饮料被一头牛选中后,就不能被其他的牛选了,问最多能满足多少头牛的要求?

    解题思路:

      最大匹配问题,关键在于如何建图,可以虚构出来一个源点,一个汇点,一共需要f+d+2*n+2个点即可,建图为:源点—>食物—>牛—>牛—>饮料—> 汇点。把牛作为点拆开建图是为了让一头牛只对应一种饮料和一种食物,避免出现对应多种饮料或者多种食物的情况。

    代码:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <algorithm>
      5 #include <iostream>
      6 #include <cmath>
      7 #include <queue>
      8 using namespace std;
      9 
     10 #define maxn 0x3f3f3f3f
     11 #define N 410
     12 int map[N][N], Layer[N], s, e;
     13 bool visit[N];
     14 bool CountLayer();
     15 int Dinic ();
     16 
     17 int main ()
     18 {
     19     int n, f, d, x, y, m;
     20     while (scanf ("%d %d %d", &n, &f, &d) != EOF)
     21     {
     22         s = 0, e = f + d + n + n + 1;
     23         memset (map, 0, sizeof(map));
     24 
     25         for (int i=1; i<=f; i++)
     26             map[0][i] = 1;//食物和源点连线
     27 
     28         for (int i=1; i<=d; i++)
     29             map[i+f+2*n][e] = 1;//饮料和汇点链接
     30 
     31         for (int i=1; i<=n; i++)
     32             map[i+f][i+f+n] = 1;//对应的牛和牛链接
     33 
     34         for (int i=1; i<=n; i++)
     35         {//建立牛和食物及饮料的关系
     36             int num = f + i;
     37             scanf ("%d %d", &x, &y);
     38             while (x --)
     39             {
     40                 scanf ("%d", &m);
     41                 map[m][num] = 1;
     42             }
     43             while (y --)
     44             {
     45                 scanf ("%d", &m);
     46                 map[num + n][m+f+2*n] = 1;
     47             }
     48         }
     49         printf ("%d
    ", Dinic());
     50     }
     51     return 0;
     52 }
     53 
     54 bool CountLayer()
     55 {
     56     deque <int> Q;
     57     memset (Layer, 0, sizeof(Layer));
     58     Layer[0] = 1;
     59     Q.push_back(0);
     60     while (!Q.empty())
     61     {
     62         int nd = Q.front();
     63         Q.pop_front();
     64         for (int i=s; i<=e; i++)
     65         {
     66             if (map[nd][i]>0 && !Layer[i])
     67             {
     68                 Layer[i] = Layer[nd] + 1;
     69                 if (i == e)
     70                     return true;
     71                 else
     72                     Q.push_back(i);
     73             }
     74         }
     75     }
     76     return false;
     77 }
     78 
     79 int Dinic ()//Dinic模板
     80 {
     81     int maxnflow = 0, i;
     82     while (CountLayer())
     83     {
     84         deque<int>Q;
     85         memset (visit, 0, sizeof(visit));
     86         visit[0] = 1;
     87         Q.push_back(0);
     88         while (!Q.empty())
     89         {
     90             int nd = Q.back();
     91             if (nd != e)
     92             {
     93                 for (i=0; i<=e; i++)
     94                 {
     95                     if (map[nd][i]>0 && Layer[i] == Layer[nd]+1 && !visit[i])
     96                     {
     97                         visit[i] = 1;
     98                         Q.push_back(i);
     99                         break;
    100                     }
    101                 }
    102                 if (i > e)
    103                     Q.pop_back();
    104             }
    105             else
    106             {
    107                 int minflow = maxn;
    108                 int mv;
    109                 for (i=1; i<Q.size(); i++)
    110                 {
    111                     int ns = Q[i-1];
    112                     int ne = Q[i];
    113                     if (map[ns][ne] < minflow)
    114                     {
    115                         minflow = map[ns][ne];
    116                         mv = ns;
    117                     }
    118                 }
    119                 maxnflow += minflow;
    120                 for (i=1; i<Q.size(); i++)
    121                 {
    122                     int ns = Q[i-1];
    123                     int ne = Q[i];
    124                     map[ns][ne] -= minflow;
    125                     map[ne][ns] += minflow;
    126                 }
    127                 while (!Q.empty() && Q.back() != mv)
    128                     Q.pop_back();
    129             }
    130         }
    131     }
    132     return maxnflow;
    133 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    题解 SP27102/UVA1747 【Swap Space】
    题解 P1453 【城市环路】
    题解 P5587 【打字练习】
    题解 P5594 【【XR-4】模拟赛】
    git add 的一点说明
    理解 Git 的基本概念 ( Merging Collaborating Rebasing)
    windows 上 Python 通过 SCP 连接linux server
    Neo4j CQL | WITH用法
    Neo4j CQL |create &merge
    Item 4: Prefer Interpolated F-Strings Over C-style Format Strings and str.format(请使用f-string格式化字符串)
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4469139.html
Copyright © 2011-2022 走看看