网络流(network-flows)是一种类比水流的解决问题方法,与线性规划密切相关。网络流的理论和应用在不断发展。而我们今天要讲的就是网络流里的一种常见问题——最大流问题。
最大流问题(maximum flow problem),一种组合最优化问题,就是要讨论如何充分利用装置的能力,使得运输的流量最大,以取得最好的效果。求最大流的标号算法最早由福特和福克逊与与1956年提出,20世纪50年代福特(Ford)、(Fulkerson)建立的“网络流理论”,是网络应用的重要组成成分。
正向边: f(u,v)< c(u,v) ——– 反向边:f(u,v)> 0
1.找出一条增广路径 ——2.修改其上点的值——3.继续重复1,直至找不出增广路。则此时源点的汇出量即为所求的最大流。
#include
#include
#define maxn 1200
#define INF 2e9
using namespace std;
int i,j,k,n,m,h,t,tot,ans,st,en;
struct node{
int c,f;
}edge[maxn][maxn];
int flag[maxn],pre[maxn],alpha[maxn],q[maxn],v;
int read(){
char c;int x;while(c=getchar(),c<'0'||c>'9');x=c-'0';
while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';return x;
}
void bfs(){
memset(flag,0xff,sizeof(flag));memset(pre,0xff,sizeof(pre));memset(alpha,0xff,sizeof(alpha));
flag[st]=0;pre[st]=0;alpha[st]=INF;h=0,t=1;q[t]=st;
while(hq[h];
for(int i=1;i<=n;i++){
if(flag[i]==-1){
if(edge[v][i].c0;pre[i]=v;alpha[i]=min(alpha[v],edge[v][i].c-edge[v][i].f);q[++t]=i;
}
else if(edge[i][v].c0){
flag[i]=0;pre[i]=-v;alpha[i]=min(alpha[v],edge[i][v].f);q[++t]=i;
}
}
}
flag[v]=1;
}
}
void Ford_Fulkerson(){
while(1){
bfs();
if(alpha[en]==0||flag[en]==-1){
break;
}
int k1=en,k2=abs(pre[k1]);int a=alpha[en];
while(1){
if(edge[k2][k1].celse if(edge[k1][k2].cif(k2==st) break;
k1=k2;k2=abs(pre[k1]);
}
alpha[en]=0;
}
}
void flow(){
int maxflow=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
if(i==st&&edge[i][j].fprintf("%d",maxflow);
}
int main(){
int u,v,c,f;
n=read();m=read();st=read();en=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) edge[i][j].c=INF,edge[i][j].f=0;
for(int i=1;i<=m;i++){
u=read();v=read();c=read();
edge[u][v].c=c;
}
Ford_Fulkerson();
flow();
return 0;
}
1.在剩余网络中查找是否存在从S到T的路径,同时建分层图。
分层图的层数其实就是S到i这个点需要几步。
2.沿着分层图多路增广。
增广时一定要满足dis[j]=dis[i]+1。
3.直到没有S到T的路径是结束算法。
#include
using namespace std;
int read(){
char c;int x;while(c=getchar(),c<'0'||c>'9');x=c-'0';
while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';return x;
}
const int MAXN=10005,MAXM=100005;
int n,m,st,en,x,y,c,H,T,ans,use,cnt=0;
int nxt[MAXM*2],head[MAXN],dis[MAXN],q[MAXM*6];
struct node{
int to,val;
}L[MAXM*2];
void add(int x,int y,int c){
L[cnt]=(node){y,c};
nxt[cnt]=head[x];
head[x]=cnt;
cnt++;
L[cnt]=(node){x,0};
nxt[cnt]=head[y];
head[y]=cnt;
cnt++;
}
int BFS(){
H=0;T=1;q[T]=st;
memset(dis,0,sizeof(dis));dis[st]=1;
while(Hint front=q[++H];use=head[front];
while(use!=-1){
if(!dis[L[use].to]&&L[use].val){
dis[L[use].to]=dis[front]+1;
q[++T]=L[use].to;
}
use=nxt[use];
}
}
return dis[en];
}
int dinic(int now,int x){
if(now==en) return x;
use=head[now];
while(use!=-1){
int rec=use;
if(dis[L[use].to]==dis[now]+1&&L[use].val){
int fd=dinic(L[use].to,min(x,L[use].val));
use=rec;
if(fd){
L[use].val-=fd;
L[use^1].val+=fd;
return fd;
}
}
use=nxt[rec];
}
return 0;
}
int main()
{
memset(head,-1,sizeof(head));
n=read();m=read();st=read();en=read();
for(int i=1;i<=m;i++){
x=read();y=read();c=read();
add(x,y,c);
}
while(BFS()){
ans+=dinic(st,2e9);
}
printf("%d",ans);
return 0;
}
#include
#include
#include
#include
using namespace std;
int read(){
char c;int x;while(c=getchar(),c<'0'||c>'9');x=c-'0';
while(c=getchar(),c>='0'&&c<='9') x=x*10+c-'0';return x;
}
const int MAXN=10005,MAXM=100005;
int N,M,S,T,x,y,c,ans;
int W[MAXM*2],To[MAXM*2],cnt;
int l[MAXM*5],h,t,dist[MAXN];
vector <int> a[MAXN];
bool BFS()
{
h=t=0;
l[++t]=S;
memset(dist,0,sizeof(dist));dist[S]=1;
while(hint front=l[++h];
for(int i=0;iint to=a[front][i];
if(!dist[To[to]] && W[to]){
dist[To[to]]=dist[front]+1;
l[++t]=To[to];
}
}
}
return dist[T];
}
int find(int now,int x)
{
if(now==T) return x;
for(int i=0;iint to=a[now][i];
if(dist[To[to]]==dist[now]+1 && W[to]){
int fd=find(To[to],min(x,W[to]));
if(fd){
W[to]-=fd;
W[to^1]+=fd;
return fd;
}
}
}
return 0;
}
int main()
{
N=read(),M=read(),S=read(),T=read();
for(int i=1;i<=M;i++){
x=read(),y=read(),c=read();
W[cnt]=c,To[cnt]=y;a[x].push_back(cnt);cnt++;
W[cnt]=0,To[cnt]=x;a[y].push_back(cnt);cnt++;
}
while(BFS()){
ans+=find(S,2e9);
}
printf("%d",ans);
return 0;
}