题意:是说有一个水池,需要通过管道排水,给出管道数,给出两个管道间的最大流量,然后让你计算最多能拍多少水。

思路:是pku上的一道模板题,注意可能有重边的问题。

code:

//Edmonds-Karp算法,BFS找增广路
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
const int INF = 1000000000;
const int MAXN = 205;

int n, m, s, t;
int a[MAXN], p[MAXN], cap[MAXN][MAXN], flow[MAXN][MAXN];
//上限容量cap,实际运送flow,从s到每个节点i的路径上最小残量a[i],则a[i]为整条路上最小残量

int main()
{
  while(scanf("%d%d", &m, &n)!=EOF)
  {
      memset(cap, 0, sizeof(cap));
      for(int i = 1; i <= m; i++)
      {
        int u, v, c;
        scanf("%d%d%d", &u, &v, &c);
        cap[u][v] += c; //注意重边
      }
      s = 1;            //源点
      t = n;          //汇点
      int ans = 0;
      queue<int> q;
      memset(flow, 0, sizeof(flow));
      for(;;)
      {
        memset(a, 0, sizeof(a));
        a[s] = INF;
        q.push(s);
        while(!q.empty()) //BFS找增广路
        {
          int u = q.front(); q.pop();
          for(int v = 1; v <= n; v++) if(!a[v] && cap[u][v]>flow[u][v])  //找到新节点
          {
            p[v] = u; q.push(v);      //记录v的父亲,加入FIFO队列
            a[v] = a[u]<(cap[u][v] - flow[u][v])?a[u]:(cap[u][v] - flow[u][v]);   //s-v路径上的最小残量
          }
        }
        if(a[t] == 0) break;          //找不到,则已经是最大值
        for(int u = t; u != s; u = p[u])  //从汇点往回走
        {
          flow[p[u]][u] += a[t];            //更新正向流量
          flow[u][p[u]] -= a[t];            //更新反向流量
        }
            ans += a[t];                        //更新从s流出的总流量
       }
        printf("%d\n", ans);
    }
  return 0;
}

posted on 2011-03-08 20:06  FreeAquar  阅读(191)  评论(0编辑  收藏  举报