POJ

来源:互联网 发布:华为java面试题 编辑:程序博客网 时间:2024/06/05 15:53

最大流模版题,练习一下

// 网络流#include <cstdio>#include <vector>#include <string.h>#include <queue>#define MAX 500#define INF 0x3fffffffusing namespace std;int c[MAX][MAX];int flow[MAX];int pre[MAX];int n, m;void init( int n ) {    memset( c, 0, sizeof( c ) );    memset( flow, 0, sizeof( flow ) );}int BFS( int s, int t ) {    queue<int> q;    for( int i = 1; i < m + 1; i++ ) {        pre[i] = -1;    }    pre[s] = 0;    flow[s] = INF;    q.push( s );    while(!q.empty() ) {        int cur = q.front();        q.pop();        if( cur == t )            //找到了增广路径            break;        for( int i = 1; i < m + 1; i++ ) {            if( i != s && c[cur][i] > 0 && pre[i] == -1 ) {                 pre[i] = cur; //记录前驱                 flow[i] = min( c[cur][i], flow[cur] );   //关键:迭代的找到增量                 q.push( i );            }        }    }    if( pre[t] == -1 )      //残留图中不再存在增广路径        return -1;    else        return flow[t];}int maxFlow( int s, int t ) {    int increasement = 0;    int sumflow = 0;    while( ( increasement = BFS( s, t ) ) != -1 ) {         int k = t;          //利用前驱寻找路径         while( k != s ) {              int last = pre[k];              c[last][k] -= increasement; //改变正向边的容量              c[k][last] += increasement; //改变反向边的容量              k = last;         }         sumflow += increasement;    }    return sumflow;}int main() {    while( scanf( "%d%d", &n, &m ) != EOF ) {        init( n );        for( int i = 0; i < n; i++ ) {            int a, b, v;            scanf( "%d%d%d", &a, &b, &v );            if( a == b ) continue;            c[a][b] += v;        }        printf( "%d\n", maxFlow( 1, m ) );    }    return 0;}