zoukankan      html  css  js  c++  java
  • POJ1149最大流

    难度在于建图,剩下的就是求最大流问题了。

    贴上我的实现代码

    //题目的难度在于如何建图,将每一个客户当做点,另外添加一个源点s和汇点t,每个客户点建一条有向边指向汇点t,容量为该客户要购买的猪的数量;
    //若客户i是猪圈j的第一个访问者,则从源点s建一条边指向节点i,容量为猪圈的初始猪数,若客户i不是猪圈j的第一个客户,而该猪圈的上一个客户(pre数组记录)是
    //x,那么从x建一条边指向i, 容量为正无穷,支持建图完成,剩下只需算出s到t的最大流即可,以下用EK算法实现; 
    #include <stdio.h>
    #include <string.h>
    #include <queue>
    using namespace std;
    const int MAXN = 1001;
    const int N = 101;
    const int MAX = 0x7FFFFFFF;
    int c[N][N], path[N], pre[MAXN], flow[N]; //pre数组记录某猪圈的前一个访问者,建图需要 
    queue<int>Q;
    int Edmonds_Karp(int s, int t) {
      int sum = 0;
      int u, v;
      while (1) {
          memset(path, -1, sizeof(path));
          while (!Q.empty())
            Q.pop();
        flow[s] = MAX;
        Q.push(s);
        while (!Q.empty() && path[t] == -1) {
             u = Q.front(); Q.pop();
             for (v = 0; v <= t; v++) {
               if (c[u][v] && path[v] == -1) {
                 path[v] = u;
                 flow[v] = flow[u] < c[u][v] ? flow[u] : c[u][v];
                 Q.push(v);
               } 
             }
        }
        if (path[t] != -1) {
          sum += flow[t];
          v = t;
          while (v != s) {
              c[path[v]][v] -= flow[t];
              c[v][path[v]] += flow[t];
              v = path[v];
          }
        } else {
          break;
        }
      }
      return sum;
    }
    
    int main()
    {
      int n1, k, order, i, j, n, m;
      int val[MAXN];
      while (scanf("%d%d", &m, &n) != EOF) {
          memset(c, 0, sizeof(c));
          memset(pre, 0, sizeof(pre));
          //以下为读取数据并建图
        for (i = 1; i <= m; i++)
            scanf("%d", &val[i]);
          for (i = 1; i <= n; i++) {
            scanf("%d", &n1);
            for (j = 0; j < n1; j++) {
                scanf("%d", &order);
                if (!pre[order]) {
                    c[0][i] += val[order]; 
                }else {
                    c[pre[order]][i] = MAX;
                }
                pre[order] = i;
            }
            scanf("%d", &k);
            c[i][n+1] = k; 
          }
          //求最大流 
          int sum = Edmonds_Karp(0, n+1);
          printf ("%d\n", sum);
      }
      return 0;
    }
  • 相关阅读:
    Kafka的Controller
    kafka 为什么能那么快?高效读写数据,原来是这样做到的
    kafka的消费
    kafka的数据同步原理ISR、ACK、LEO、HW
    kafka 工作流程及文件存储机制
    kafka的简单架构
    Sangfor AC在线用户显示大量公网IP
    H3C抓包命令
    Android- 音量控制
    call指令的地址是怎么计算出来的。
  • 原文地址:https://www.cnblogs.com/Patrickcxt/p/3226648.html
Copyright © 2011-2022 走看看