标签:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
#define Size 200
int Gra[Size+1][Size+1];// 由于是单向边 所以一个矩阵可以表示一个带有反向边的残余网络
bool Visited[Size+1];
int Pre[Size+1]; // 前驱节点 用来形成一条从源点到汇点的路径
int N, M, S, E, C;// 输入数据
int EK()
{
memset( Visited, 0, sizeof(Visited) );
Pre[1] = 0;
Visited[1] = true;
queue<int>Que;
bool FindPath = false; // 标记是否找到 一条增广路径
Que.push(1);
while( !Que.empty() )
{
int T = Que.front();
Que.pop();
for( int i=1; i<=M; i++ )// 广搜遍历所有顶点
if( Gra[T][i]>0 && !Visited[i] )
{
Pre[i] = T;
Visited[i] = true;
if( i==M )
{
FindPath = true;
Que.empty(); // 清空 以便 跳出while
break;
}
else
Que.push(i);
}
}
if( !FindPath )
return 0; // 未找到一条增广路径
int RateFlow = 1<<30;
int V = M;
while( Pre[V] ) // 追溯 路径上的最小值 即最终汇流量
{
RateFlow = min( RateFlow, Gra[Pre[V]][V] );
V = Pre[V];
}
V = M;
while( Pre[V] )
{
Gra[Pre[V]][V] -= RateFlow;
Gra[V][Pre[V]] += RateFlow;
V = Pre[V];
}
return RateFlow;
}
int main()
{
while( ~scanf( "%d%d", &N, &M ) )
{
memset( Gra, 0, sizeof(Gra) );
for( int i=0; i<N; i++ )
{
scanf( "%d%d%d", &S, &E, &C );
Gra[S][E] += C; // 有重边
}
int ans = 0;
int n;
while( n=EK() )
ans += n;
printf( "%d\n", ans );
}
return 0;
}
POJ-1273-Drainage Ditches:网络流入门第一题
标签:
原文地址:http://www.cnblogs.com/FightForCMU/p/4684732.html