网络流是一个联通图;
网络流有如下三个性质:
1.一条边上容量恒大于流量,即c(i,j)>=f(i,j)
2.斜对称性,f(u,v)=-f(v,u);
3.对于非源点和汇点有∑{f(i,j)}{i,j属于E}=0;
为了更方便算法的实现,一般根据原网络定义一个残量网络。其中r(u,v)为残量网络的容量。
r(u,v) = c(u,v) – f(u,v)
*反向边也有r!!!!
增广路是指一条源点到汇点的链,链上满足r(u,v)>0就可以对其进行增广!
可以用dfs 或bfs实现
#include<cstdlib> #include<cstdio> #include<iostream> #include<queue> #include<algorithm> #include<vector> #include<cstring> #define MAXX 1100 #define INF 1000000000 using namespace std; struct node{ int to,c,re; }; vector<node>edge[MAXX*4]; bool vis[MAXX]; int n,m,x,y,z; void add(int from,int to,int ww){ edge[from].push_back((node){to,ww,edge[to].size()}); edge[to].push_back((node){from,0,edge[from].size()-1}); } int dfs(int s,int t,int T){ if(s==t)return T; vis[s]=true; for(int i=0;i<edge[s].size();++i){ node &tp=edge[s][i]; if(vis[tp.to]==false&&tp.c>0){ int dd=dfs(tp.to,t,min(T,tp.c)); if(dd>0){ tp.c-=dd; edge[tp.to][tp.re].c+=dd; return dd; } } } return 0; } int maxflow(int s,int t){ int flow=0; while(1){ memset(vis,false,sizeof(vis)); int f=dfs(s,t,INF); if(f==0)return flow; flow+=f; } } int main(){ while(scanf("%d%d",&n,&m)!=EOF){ memset(edge,0,sizeof(edge)); for(int i=1;i<=n;++i){ scanf("%d%d%d",&x,&y,&z); add(x,y,z); } printf("%d ",maxflow(1,m)); } return 0; }