HDOJ Flow Problem 3549(最大流)

来源:互联网 发布:qq飞车绿光使者数据 编辑:程序博客网 时间:2024/06/03 15:49

Flow Problem

Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 9642    Accepted Submission(s): 4509


Problem Description
Network flow is a well-known difficult problem for ACMers. Given a graph, your task is to find out the maximum flow for the weighted directed graph.
 

Input
The first line of input contains an integer T, denoting the number of test cases.
For each test case, the first line contains two integers N and M, denoting the number of vertexes and edges in the graph. (2 <= N <= 15, 0 <= M <= 1000)
Next M lines, each line contains three integers X, Y and C, there is an edge from X to Y and the capacity of it is C. (1 <= X, Y <= N, 1 <= C <= 1000)
 

Output
For each test cases, you should output the maximum flow from source 1 to sink N.
 

Sample Input
23 21 2 12 3 13 31 2 12 3 11 3 1
 

Sample Output
Case 1: 1Case 2: 2
 

Author
HyperHexagon
 

Source
HyperHexagon's Summer Gift (Original tasks)
 

Recommend
zhengfeng   |   We have carefully selected several similar problems for you:  1532 3572 3416 3081 3491

最大流模板题~
残余网络:正常的边、反向边共同构成的图称为残余网络。概念可以参见看bin神博客:点击打开链接。
不理解“增广路”的概念,百度好久。。感觉这个讲的较好



首先,假如所有边上的流量都没有超过容量(不大于容量),那么就把这一组流量,或者说,这个流,称为一个可行流。一个最简单的例子就是,零流,即所有的流量都是0的流。

我们就从这个零流开始考虑,假如有这么一条路,这条路从源点开始一直一段一段的连到了汇点,并且,这条路上的每一段都满足流量<容量,注意,是严格的<,而不是<=。那么,我们一定能找到这条路上的每一段的(容量-流量)的值当中的最小值delta。我们把这条路上每一段的流量都加上这个delta,一定可以保证这个流依然是可行流,这是显然的。

    这样我们就得到了一个更大的流,他的流量是之前的流量+delta,而这条路就叫做增广路。

    我们不断地从起点开始寻找增广路,每次都对其进行增广,直到源点和汇点不连通,也就是找不到增广路为止。当找不到增广路的时候,当前的流量就是最大流,这个结论非常重要。

寻找增广路的时候我们可以简单的从源点开始做bfs,并不断修改这条路上的delta量,直到找到源点或者找不到增广路。


上代码~,记得清空图~不清的话超时。

Frod-Fulkerson算法

#include <iostream>#include<stdio.h>#include<string.h>#include<queue>#include<algorithm>#define maxn 20#define INF 0x3f3f3f3fusing namespace std;struct edge{int to,cap,rev;};vector<edge> G[maxn];bool used[maxn];//向图中增加一条从s到t容量为cap的边void add_edge(int from,int to,int cap){G[from].push_back((edge){to,cap,G[to].size()});G[to].push_back((edge){from,0,G[from].size()-1});}//通过DFS寻找增广路//f代表deltaint dfs(int v,int t,int f){if(v==t)return f;      //当前点是终点返回fused[v]=true;for(int i=0;i<G[v].size();i++){edge &e=G[v][i];if(!used[e.to]&&e.cap>0){int d=dfs(e.to,t,min(f,e.cap));if(d>0){e.cap-=d;G[e.to][e.rev].cap+=d;return d;}}}return 0;}//求解s到t的最大流int max_flow(int s,int t){int flow=0;while(1){memset(used,0,sizeof(used));int f=dfs(s,t,INF);if(f==0) return flow;flow+=f;}}int main(){int t;int x=1;scanf("%d",&t);int N,M;while(t--){scanf("%d%d",&N,&M);for(int i=0;i<=N;i++)G[i].clear();int from,to,cap;for(int i=0;i<M;i++){scanf("%d%d%d",&from,&to,&cap);add_edge(from,to,cap);}printf("Case %d: %d\n",x++,max_flow(1,N));}    return 0;}


 
0 0