您的位置:首页 > 大数据 > 人工智能

HDU 1532 Drainage Ditches 排水渠(最大流,入门)

2015-07-12 15:21 513 查看
题意:

  给出一个有向图,以及边上的容量上限,求最大流。(有重边,要将容量上限叠加)

思路:

  用最简单的EK+BFS解决。每次搜到一条到达终点的路径,就立刻退出,更新ans,然后再回头修改图中的当前flow状况(这就得靠记录路径了)。当当前图没有到达终点的路径图,流已经饱和,可以结束程序了。

#include <bits/stdc++.h>
#define LL long long
#define pii pair<int,int>
#define INF 0x7f7f7f7f
using namespace std;
const int N=200+5;

vector<int> vect
;
int c

;    //容量
int flow

; //流量

int a
;       //临时流量
int path
;    //得记录用的是哪条边,好更新flow和cap

int BFS(int m)
{
deque<int> que;
que.push_back(1);
a[1]=INF;       //先置为无穷大

while(!que.empty())
{
int x=que.front();
que.pop_front();
for(int i=0; i<vect[x].size(); i++)
{
int t=vect[x][i];
if(!a[t] && c[x][t]>flow[x][t] )  //未遍历过,且容>流
{
path[t]=x;                       //只需要记得到达t的是哪个点
a[t]=min(a[x], c[x][t]-flow[x][t]);     //要么全部流给你,要么取能流过的上限
que.push_back(t);
}
}
if(a[m])    return a[m];  //只要有路径能够更新到终点m,立刻退出。
}
return 0;
}

int cal(int m)
{
int ans_flow=0;
while(true)                     //求最大流
{
memset(a,0,sizeof(a));
memset(path,0,sizeof(path));

int tmp=BFS(m);
if(!tmp)    return ans_flow;    //找不到增广路了
ans_flow+=tmp;

int ed=m;
while(ed!=1)        //根据路径调整一下流及上限
{
int from=path[ed];
flow[from][ed]+=tmp;        //正向边加流量
flow[ed][from]-=tmp;        //反向边减流量,相当于cap-flow一样大于0。
ed=from;
}
}
}

int main()
{
freopen("input.txt", "r", stdin);
int n, m, st, ed, ca;
while(~scanf("%d%d",&n,&m))
{

for(int i=0; i<=m; i++) vect[i].clear();
memset(c, 0, sizeof(c));
memset(flow, 0, sizeof(flow));

for(int i=0; i<n; i++)
{
scanf("%d %d %d", &st, &ed, &ca);
vect[st].push_back(ed);             //邻接表
vect[ed].push_back(st);             //反向边,容量是0的。
c[st][ed]+=ca;                      //坑在这
}
cout<<cal(m)<<endl;

}
return 0;
}


AC代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: