poj1273 Drainage Ditches

基础的网络最大流。。。Edmonds-Karp算法飘过。。

#include <iostream>
#include <queue>
using namespace std;
struct node
{
       int num, value;      
};
const int size = 210;
int mapp[size][size];//原流量
int resmapp[size][size];//残余流量
int father[size];
bool visited[size];
int flow[size][size];//记录最大流的值
int Edmonds_Karp(int s, int e)
{
     bool flag = true;//标记是否能够找到增广路;
     memset(flow, 0, sizeof(flow));
     while (flag){
           flag = false;
           memset(visited, false, sizeof(visited));
           queue <node> que;
           node pre;
           pre.num = s, pre.value = INT_MAX;
           father[s] = 0;
           que.push(pre);
           visited[s] = true;
           while (!que.empty()){
                 pre = que.front();
                 que.pop();
                 for (int i = 1; i <= e; i ++){
                     node next;
                     next.num = i;
                     int pr = pre.num, ne = next.num;
                     if (pr == ne || !resmapp[pr][ne] || visited[ne])continue;//显然子节点不能是父节点、而且子节点到父节点要有剩余流量和子节点未曾被访问
                     father[ne] = pr;
                     next.value = min(pre.value, resmapp[pr][ne]);
                     que.push(next);      
                     visited[i] = true;
                     if (i == e){//已经找到一条增广路
                        flag = true;
                        break;
                     }
                 }     
                 if (flag)break;
           }
           //修改流量
           if (flag){
              int u, v;//u为当前节点,v为其父节点
              u = e, v = father[u];//从汇点开始
              int val = que.back().value;
              while (v){
                    flow[u][v] += val;
                    flow[v][u] = -flow[u][v];//据最大流的反对称性
                    resmapp[u][v] = mapp[u][v] - flow[u][v];//修改残余流量
                    resmapp[v][u] = mapp[v][u] - flow[v][u];    
                    u = v, v = father[u];
              }
           }
     }
     int max_flow = 0;
     for (int i = 2; i <= e; i ++){
         max_flow += flow[s][i];  //由于题意要求当前管道到池塘的总流量    
     }
     return max_flow;
}
int main()
{
    int n, m;
    while (scanf("%d%d", &n, &m) != EOF){
          memset(mapp, 0, sizeof(mapp));
          for (int i = 0; i < n; i ++){
              int a, b, c;
              scanf("%d%d%d", &a, &b, &c);
              mapp[a][b] += c;
              resmapp[a][b] = mapp[a][b];
          }     
          printf("%d\n", Edmonds_Karp(1, m));
    }
    return 0;   
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值