• POJ3281 Dining(拆点构图 + 最大流)


    题目链接

    题意:有F种食物,D种饮料N头奶牛,只能吃某种食物和饮料(而且只能吃特定的一份)

    一种食物被一头牛吃了之后,其余牛就不能吃了
    第一行有N,F,D三个整数
    接着2-N+1行代表第i头牛,前面两个整数是Fi与Di(食物与饮料的种类数量),接着是食物的种类与饮料的种类
    要求输出最多分配能够满足的牛的数量

    参考北理大神博客

    分析:本想最大匹配搞,然后发现牛不仅要匹配食物还要匹配饮料。

    最大流拆点构图, 食物 - 牛- 饮料,但是由于一个牛只能选择一个食物和一个饮料,也就是说牛这个节点有限制,最大就是1,然后把 牛这个节点拆成 牛 - 牛 其中之间流量是1,

    于是 最后模型就是 食物 - 牛 - 牛 - 饮料  节点之间的流量都是1.

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <queue>
     5 #include <cstring>
     6 using namespace std;
     7 const int Max = 500;
     8 const int INF = 0x3f3f3f3f;
     9 int g[Max][Max];
    10 int N, F, D;
    11 int pre[Max];
    12 int BFS()
    13 {
    14     memset(pre, -1, sizeof(pre));
    15     int MinFlow = INF;
    16     queue<int> que;
    17     pre[0] = 0;
    18     que.push(0);
    19     int des = F + 2 * N + D + 1;
    20     while (!que.empty())
    21     {
    22         int x = que.front();
    23         que.pop();
    24         if (x == des)
    25             break;
    26         for (int i = 1; i <= des; i++)
    27         {
    28             if (pre[i] == -1 && g[x][i])
    29             {
    30                 if (MinFlow > g[x][i])
    31                 {
    32                     MinFlow = g[x][i];
    33                 }
    34                 pre[i] = x;
    35                 que.push(i);
    36             }
    37         }
    38     }
    39     if (pre[des] == -1)
    40         return -1;
    41     return MinFlow;
    42 }
    43 void EK()
    44 {
    45     int MaxFlow = 0, inFlow = 0, des;
    46     while ( (inFlow = BFS()) != -1)
    47     {
    48         MaxFlow += inFlow;
    49         des = F + 2 * N + D + 1;
    50         while (des != 0)
    51         {
    52             g[des][pre[des]] += inFlow;
    53             g[pre[des]][des] -= inFlow;
    54             des = pre[des];
    55         }
    56     }
    57     printf("%d
    ", MaxFlow);
    58 }
    59 void buildGraph()
    60 {
    61     while (scanf("%d%d%d", &N, &F, &D) != EOF)
    62     {
    63         memset(g, 0, sizeof(g));
    64         int fd, fnum, dnum;
    65         for (int i = 1; i <= N; i++)
    66         {
    67             scanf("%d%d", &fnum, &dnum);
    68             for (int j = 0; j < fnum; j++)
    69             {
    70                 scanf("%d", &fd);
    71                 g[0][fd] = 1;  // 0点作为起点连接每个食物
    72                 g[fd][F + i] = 1; // 食物和牛相连,食物最大F,
    73             }
    74             g[F + i][F + N + i] = 1; // 牛 和 牛相连 
    75             for (int j = 1; j <= dnum; j++)
    76             {
    77                 scanf("%d", &fd);
    78                 g[F + N + i][F + N + N + fd] = 1;  // 牛和饮料相连
    79                 g[F + N + N + fd][F + N + N + D + 1] = 1; // 设一个终点让每一个 饮料 和他相连,流量为1
    80             }
    81         }
    82         EK();
    83     }
    84 }
    85 int main()
    86 {
    87     buildGraph();
    88     return 0;
    89 }
    View Code
  • 相关阅读:
    补题报告 个人赛2020.4.12
    UCF Local Programming Contest 2017 2020.4.7
    比赛:ICPC Asia Taipei-Hsinchu Regional 2019 2020.4.1
    UCF Local Programming Contest 2016 2020.3.28
    Benelux Algorithm Programming Contest 2019 2020/3/21
    比赛名:Preliminaries for Benelux Algorithm Programming Contest 2019 时间2020.3.14
    【Scala】Scala使用scalikejdbc工具连接MySQL(推荐)
    【Scala】Scala使用JDBC连接Mysql/权限问题
    【异常】Specified key was too long;max key length is 767 bytes、解决由于HDFS格式化造成Hive数据全部丢失的问题
    【异常】Hive作业异常kill :Hadoop MapReduce Error
  • 原文地址:https://www.cnblogs.com/zhaopAC/p/5409511.html
Copyright © 2020-2023  润新知