poj1273 Drainage Ditches 基础网络流
阅读原文时间:2023年07月11日阅读:2

#include
#include
using namespace std;
int G[][];
int Prev[]; //路径上每个节点的前驱节点
bool Visited[];
int n,m; //m是顶点数目,顶点编号从1开始 1是源,m是汇, n是 边数

int Augment()
{
int v;
int i;
deque q;
memset(Prev,,sizeof(Prev));
memset(Visited,,sizeof(Visited));
Prev[] = ;
Visited[] = ;
q.push_back();
bool bFindPath = false;
//用bfs寻找一条源到汇的可行路径
while (!q.empty())
{
v = q.front();
q.pop_front();
for (i = ; i <= m; i++) { if (G[v][i] > && Visited[i] == )
{
//必须是依然有容量的边,才可以走
Prev[i] = v;
Visited[i] = ;
if( i == m )
{
bFindPath = true;
q.clear();
break;
}
else
q.push_back(i);
}
}
}

 if (!bFindPath)  
     return ;  
 int nMinFlow = ;  
 v = m;  //寻找源到汇路径上容量最小的边,其容量就是此次增 加的总流量  
 while( Prev\[v\] )  
 {  
     nMinFlow = min( nMinFlow,G\[Prev\[v\]\]\[v\]);  
     v = Prev\[v\];  
 }  
 //沿此路径添加反向边,同时修改路径上每条边的容量  
 v = m;  
 while( Prev\[v\] )  
 {  
     G\[Prev\[v\]\]\[v\] -= nMinFlow;  
     G\[v\]\[Prev\[v\]\] += nMinFlow;  
     v = Prev\[v\];  
 }  
 return nMinFlow;  

}

int main()
{
while (cin >> n >> m)
{
//m是顶点数目,顶点编号从1开始
int i,j,k;
int s,e,c;
memset( G,,sizeof(G));
for( i = ;i < n;i ++ ) { cin >> s >> e >> c;
G[s][e] += c; //两点之间可能有多条边
}
int MaxFlow = ;
int aug;
while( aug = Augment() )
MaxFlow += aug;
cout << MaxFlow << endl;
}
return ;
}