POJ 3544

来源:互联网 发布:caffe 深度学习 编辑:程序博客网 时间:2024/05/01 23:25
#include <bits/stdc++.h>const int INF = 0x7f7f7f7f;using namespace std;int flow[205][205], cap[205][205], p[205], c[205];  // f用来记录单前节点流,p用来记录父路径void BFS( int&maxflow, int N ){    queue<int>q;    maxflow = 0;    bool finish = false;    memset( flow, 0, sizeof( flow ) );    while ( !finish )    {        memset( p, 0, sizeof( p ) );        memset( c, 0, sizeof( c ) );        c[1] = INF, p[1] = -1;        q.push( 1 );        while ( !q.empty() )        {            int pos = q.front();            q.pop();            for ( int i = 1; i <= N; ++i )            {                if ( !c[i] && flow[pos][i] < cap[pos][i] ) // 如果该条边没有达到饱和或者形成回流                {                    c[i] = min( c[pos], cap[pos][i] - flow[pos][i] ); // 选取当前管道残留容量和截止到上一次的路径残留容量之间的较小者,可以看作是一种更新                    // 即该增广路径的残留容量是有路径中残留容量最小的管道决定的                    p[i] = pos; // 记录父亲路径                    q.push( i );                }            }        }        if ( c[N] == 0 )        {            finish = true;        }        maxflow += c[N];        int pos = N;        while ( !finish && pos != 1 )        {            flow[ p[pos] ][ pos ] += c[N];            flow[ pos ][ p[pos] ] -= c[N];            pos = p[ pos ];        }    }}int main(int argc, char const *argv[]){    int N, M, maxflow, ca = 0, T;    scanf( "%d", &T );    while ( T-- )    {        scanf( "%d %d", &M, &N );        memset( cap, 0, sizeof( cap ) );        for ( int i = 1; i <= N; ++i )        {            int x, y, z;            scanf( "%d %d %d", &x, &y, &z );            cap[x][y] += z;        }        BFS( maxflow, M );        printf( "Case %d: %d\n", ++ca, maxflow );    }    return 0;}

网络流模板题

0 0
原创粉丝点击