网络流是一个联通图;
网络流有如下三个性质:
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\n",maxflow(1,m));
}
return 0;
}