poj1459 网络最大流问题 ek算法

来源:互联网 发布:怎么用php做菱形 编辑:程序博客网 时间:2024/04/29 21:21

1459是一道经典的最大流问题,很适合练手,最大流问题有很多算法,经典的像ek、km,在ACM比赛中,一般由于时间紧迫,比较适合用ek,因为直观,写起来不是很费力。

下面来回顾一下ek算法的经典流程,ek算法有两个函数组成:

1.ek主函数;2.dfs函数。

ek主函数的输入参数为起始编号,终止编号:

void ek(int start,int end){int max=0;int min=dfs(0,node+1);while(min!=0){max+=flow[last];int last=node+1;while(last!=0){g[former[last]][last]-=min;g[last][former[last]]+=min;last=former[last];}min=bfs(0.node+1);}}


bfs函数,寻找一条增广路:

int bfs(int start,int end){queue<int> q;while(!q.empty()){q.pop();}bool ifVisited[node+2];for(int i=1;i<=node+2;i++){ifVisited[i]=false;flow[i]=0}flow[0]=999999;ifVisited[0]=true;q.push(0);while(!q.empty()){int v=q.front();q.pop();for(int i=1;i<=node+2;i++){if(ifVisited[i]==false&&grid[v][i]>0){ifVisited[i]=true;flow[i]=flow[v]<grid[v][i]?flow[v]:grid[v][i];q.push(i);former[i]=v;}}}return flow[node+1];}


代码如下:

#include<iostream>#include<queue>using namespace std; int station,consumer,node,deliver;int grid[205][205];int former[205];int flow[205];int bfs(int start,int end){queue<int> q;while(!q.empty()){q.pop();}bool ifVisited[node+2];for(int i=1;i<=node+2;i++){ifVisited[i]=false;flow[i]=0}flow[0]=999999;ifVisited[0]=true;q.push(0);while(!q.empty()){int v=q.front();q.pop();for(int i=1;i<=node+2;i++){if(ifVisited[i]==false&&grid[v][i]>0){ifVisited[i]=true;flow[i]=flow[v]<grid[v][i]?flow[v]:grid[v][i];q.push(i);former[i]=v;}}}return flow[node+1];}int main(){while(cin>>node){cin>>station>>consumer>>deliver;for(int i=1;i<=node;i++){for(int j=1;j<=node;j++){grid[i][j]=0;}}for(int i=1;i<=deliver;i++){char temp;int a,b,c;cin>>temp>>a>>temp>>b>>temp>>c;grid[a][b]=c;}for(int i=1;i<=station;i++){char temp;int a,b;cin>>temp>>a>>temp>>b;grid[0][a]=b;}for(int i=1;i<=consumer;i++){char temp;int a,b;cin>>temp>>a>>temp>>b;grid[a][node+1]=b;}int max=0;int min=dfs(0,node+1);while(min!=0){max+=flow[last];int last=node+1;while(last!=0){g[former[last]][last]-=min;g[last][former[last]]+=min;last=former[last];}min=bfs(0.node+1);}cout<<max<<endl;}return 0;}


0 0
原创粉丝点击