HDU1532 - Drainage Ditches : http://acm.hdu.edu.cn/showproblem.php?pid=1532
虽然我不懂,但还是要装逼的说这只是一道模板题= =!(对着别人代码敲了一遍)
代码 :
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN = 205;
const int INF = 1<<29;
int Map[MAXN][MAXN],Path[MAXN],Flow[MAXN];//Map存的是路径,Path[i] = x表示i的前一个节点是x(当然可能有多个,看深搜的路径),Flow[i]表示i节点的流量
int N,M;
int St,End,S,E,V;
queue<int>q;
int BFS()
{
fill(Path,Path + MAXN,-1);
while(!q.empty())q.pop();//清空队列
Path[St] = 0,Flow[St] = INF;
q.push(St);
while(!q.empty())
{
int t = q.front();
q.pop();
if(t == End)break;//找到一条到终点的路径
for(int i = 1;i <= M;i++)
{
if(Map[t][i] && Path[i] == -1)
{
q.push(i);
Path[i] = t;
Flow[i] = Flow[t] < Map[t][i] ? Flow[t] : Map[t][i];//更新可以到达i的最大流量
}
}
}
if(Path[End] == -1)return -1;
return Flow[End];
}
int Edmonds_Karp()
{
int MaxFlow = 0,Flow = 0,Now,Pre;
while((Flow = BFS()) != -1)//每次都找出一条通往终点的路径(注意这里反边也是可以走的)
{
MaxFlow += Flow;//最大流量
Now = End;
while(Now != St)//给广搜出来的边(路径)都加上一条反边(建立后反边可走)
{
Pre = Path[Now];
Map[Pre][Now] -= Flow;
Map[Now][Pre] += Flow;
Now = Pre;
}
}
return MaxFlow;
}
int main()
{
while(~scanf("%d%d",&N,&M))
{
fill(&Map[0][0],&Map[MAXN][0],0);
while(N--)
{
scanf("%d%d%d",&S,&E,&V);
Map[S][E] += V;//防止重边
}
St = 1,End = M;
printf("%d\n",Edmonds_Karp());
}
return 0;
}