POJ 1273 Drainage Ditches

来源:互联网 发布:如何理解软件定义网络 编辑:程序博客网 时间:2024/04/26 20:51

转载请注明出处:http://blog.csdn.net/drecik__/article/details/7406127

/*  * 第二道网络流, 直接套用之前1149的连续最短增广路法; * 由于未考虑到重边, 无耻的WA了一次; */#include <iostream>#include <queue>#include <cstring>#include <cstdio>using namespace std;#define MAXN 205#define INF 999999999#define MIN( a, b ) ( (a) <= (b)? (a):(b) )#define ABS( a ) ( (a) >= 0? (a) : -(a) )// 边的属性结构;struct EdgeType{int c;int f;      // 容量和流量; };EdgeType Edges[MAXN][MAXN]; // 邻接矩阵, 当两点之间不存在边时,c和f都赋值为INF; int flag[MAXN];             // 标记, -1:未标记,0:已标记未检查,1:标记并检查;int prar[MAXN];             // 标号的第一个分量,用于存放父节点;int alpha[MAXN];            // 标号的第二个分量,存放可改进a;int level[MAXN];// 各个顶点的等级;void BFS( int s, int n ){memset( level, 0, sizeof(level) );queue<int> queInt;queInt.push( s );while ( !queInt.empty() ){int u = queInt.front();queInt.pop();for ( int i = 0; i < n; ++i ){if ( i == s )continue;if ( !level[i] && Edges[u][i].c < INF && Edges[u][i].f < Edges[u][i].c ){level[i] = level[u]+1;queInt.push(i);}if ( !level[i] && Edges[i][u].c < INF && Edges[i][u].f > 0 ){level[i] = level[u]+1;queInt.push(i);}}}}// 进行深搜, 搜索的点, 汇点, 顶点个数;int DFS( int s, int t, int n ){if ( s == t )return alpha[t];// 标记为已读;flag[s] = 0;// 用于存放回溯是的增量;int sumAlpha = 0;for ( int i = 0; i < n; ++i ){if ( flag[i] == -1 && level[i] == level[s]+1 ){// 正向边;if ( Edges[s][i].c < INF && Edges[s][i].f < Edges[s][i].c ){// 进行标记;prar[i] = s;alpha[i] = MIN( alpha[s], Edges[s][i].c-Edges[s][i].f );int x = DFS( i, t, n );Edges[s][i].f += x;alpha[s] -= x;sumAlpha += x;}// 反向边;if ( Edges[i][s].c < INF && Edges[i][s].f > 0 ){// 进行标记;prar[i] = s;alpha[i] = MIN( alpha[s], Edges[i][s].f );int x = DFS( i, t, n );Edges[i][s].f -= x;alpha[s] -= x;sumAlpha += x;}}}flag[s] = -1;return sumAlpha;}// 第一个参数为源点,第二个为汇点; int Ford( int s, int t, int n ){// 进行寻找增广路径;while ( BFS( s, n ), level[t] ){// 对标号进行初始化;memset( flag, 0xff, sizeof(flag) );// 对分量进行初始化;memset( prar, 0xff, sizeof(prar) );memset( alpha, 0xff, sizeof(alpha) ); alpha[s] = INF;prar[s] = s;DFS( s, t, n );}// 存放最大流; int iMaxFlow = 0;for ( int i = 0; i < n; ++i ){if ( Edges[s][i].f < INF )iMaxFlow += Edges[s][i].f;}return iMaxFlow;}int main(){int iPointNum, iEdgeNum;// 顶点和边的数量;while ( ~scanf( "%d%d", &iEdgeNum, &iPointNum ) ){// 初始化邻接矩阵; for ( int i = 0; i < iPointNum; ++i ){for ( int j = 0; j < iPointNum; ++j ){Edges[i][j].c = INF;Edges[i][j].f = INF;}}while( iEdgeNum-- ){int u, v, c;scanf( "%d%d%d", &u, &v, &c );if ( Edges[u-1][v-1].c < INF )Edges[u-1][v-1].c += c;elseEdges[u-1][v-1].c = c;Edges[u-1][v-1].f = 0;}cout << Ford( 0, iPointNum-1, iPointNum ) << endl;}return 0;}

原创粉丝点击