「网络流」学习笔记

· · 个人记录

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
const int Maxn=1e4+5;
const int Maxm=3e5+5;
const int inf=1e9;
struct edge{
    int v,w,nx;
}e[Maxm];
int n,m,sc,tc,ans,ne=-1,f[Maxn],deep[Maxn],cur[Maxn];
queue<int> q;
bool bfs(int s,int t)
{   memset(deep,0x7f,sizeof(deep));
    for(int i=0;i<=n+5;i++)cur[i]=f[i];
    while(!q.empty())q.pop();
    deep[s]=0;
    q.push(s);
    while(!q.empty())
    {   int now=q.front();
        q.pop();
        for(int i=f[now];i!=-1;i=e[i].nx)
            if(e[i].w&&deep[e[i].v]>=inf)
            {   deep[e[i].v]=deep[now]+1;
                q.push(e[i].v);
            }
    }
    return deep[t]<inf;
}
int dfs(int now,int t,int limit)
{   if(!limit||now==t)return limit;
    int flow=0,x;
    for(int i=cur[now];i!=-1;i=e[i].nx)
    {   cur[now]=i;
        if(deep[e[i].v]==deep[now]+1)
        {   x=dfs(e[i].v,t,min(limit,e[i].w));
            if(x==0)continue;
            flow+=x;
            limit-=x;
            e[i].w-=x;
            e[i^1].w+=x;
            if(limit==0)break;
        }
    }
    return flow;
}
int dinic(int s,int t)
{   int maxflow=0;
    while(bfs(s,t))maxflow+=dfs(s,t,inf);
    return maxflow;
}
void read(int u,int v,int w)
{   e[++ne].v=v;
    e[ne].w=w;
    e[ne].nx=f[u];
    f[u]=ne;
}
int main()
{   memset(f,-1,sizeof(f));
    int s,t;
    scanf("%d%d%d%d",&n,&m,&s,&t);
    for(int i=1;i<=m;i++)
    {   int u,v,w;
        scanf("%d%d%d",&u,&v,&w);
        read(u,v,w);read(v,u,0);
    }
    printf("%d\n",dinic(s,t));
    return 0;
}
scanf("%d%d",&n,&m);
s=n+1,t=n+2;
for(int i=1;i<=m;i++)
{   int u,v;
    scanf("%d%d%d%d",&u,&v,&cl[i],&cu[i]);
    a[u]-=cl[i];a[v]+=cl[i];
    read(u,v,cu[i]-cl[i]);
    read(v,u,0);
}
int sum=0;
for(int i=1;i<=n;i++)
    if(a[i]>0)sum+=a[i],read(s,i,a[i]),read(i,s,0);
    else if(a[i]<0)read(i,t,-a[i]),read(t,i,0);
int flow=dinic(s,t);
if(flow<sum)printf("NO\n");
else{
    printf("YES\n");
    for(int i=1;i<=m*2;i+=2)
        printf("%d\n",e[i].w+cl[i/2+1]);
}
memset(f,-1,sizeof(f));
int s,t,S,T; 
scanf("%d%d%d%d",&n,&m,&S,&T);
s=n+1;t=n+2;
for(int i=1;i<=m;i++)
{   int u,v;
    scanf("%d%d%d%d",&u,&v,&cl[i],&cu[i]);
    a[u]-=cl[i];a[v]+=cl[i];
    read(u,v,cu[i]-cl[i]);
    read(v,u,0);
}
int sum=0;
for(int i=1;i<=n;i++)
    if(a[i]>0)sum+=a[i],read(s,i,a[i]),read(i,s,0);
    else if(a[i]<0)read(i,t,-a[i]),read(t,i,0);
read(T,S,inf);read(S,T,0);
if(dinic(s,t)<sum)printf("No Solution\n");
else{
    int res=e[ne].w;
    e[ne].w=e[ne-1].w=0;
    printf("%d\n",res+dinic(S,T));
}
memset(f,-1,sizeof(f));
int s,t,S,T; 
scanf("%d%d%d%d",&n,&m,&S,&T);
s=n+1;t=n+2;
for(int i=1;i<=m;i++)
{   int u,v;
    scanf("%d%d%d%d",&u,&v,&cl[i],&cu[i]);
    a[u]-=cl[i];a[v]+=cl[i];
    read(u,v,cu[i]-cl[i]);
    read(v,u,0);
}
int sum=0;
for(int i=1;i<=n;i++)
    if(a[i]>0)sum+=a[i],read(s,i,a[i]),read(i,s,0);
    else if(a[i]<0)read(i,t,-a[i]),read(t,i,0);
read(T,S,inf);read(S,T,0);
if(dinic(s,t)<sum)printf("No Solution\n");
else{
    int res=e[ne].w;
    e[ne].w=e[ne-1].w=0;
    printf("%d\n",res-dinic(T,S));
}
return 0;
scanf("%d%d",&n,&m);
n++;s=0;t=n;
for(int i=0;i<=n;i++)f[i]=-1;
for(int i=1;i<n;i++)
{   int x;
    scanf("%d",&x);
    if(x)
    {   read(s,i,1);
        read(i,s,0);
    }
    else{
        read(t,i,0);
        read(i,t,1);
    }
}
for(int i=1;i<=m;i++)
{   int x,y;
    scanf("%d%d",&x,&y);
    read(x,y,1);
    read(y,x,1);
}
printf("%d\n",dinic(s,t));
//这个是 EK
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
const int Maxn=5000+5,Maxm=50000+5;
const int inf=1e9;
int n,m,ne=-1,s,t,f[Maxn];
int maxflow,mincost,dis[Maxn],incf[Maxn],pre[Maxn];
bool vis[Maxn];
queue<int>q;
struct edge{
    int v,w,c,nx;
}e[Maxm<<1];
void read(int u,int v,int w,int c)
{   e[++ne].v=v;
    e[ne].w=w;
    e[ne].c=c;
    e[ne].nx=f[u];
    f[u]=ne;
}
bool spfa()
{   for(int i=0;i<=n;i++)dis[i]=inf;
    memset(vis,0,sizeof(vis));
    q.push(s);
    dis[s]=0;vis[s]=1;
    incf[s]=inf;
    while(!q.empty())
    {   int u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=f[u];i!=-1;i=e[i].nx)
        {   int v=e[i].v;
            if(e[i].w==0)continue;
            if(dis[u]+e[i].c<dis[v])
            {   dis[v]=dis[u]+e[i].c;
                incf[v]=min(incf[u],e[i].w);
                pre[v]=i;
                if(!vis[v])q.push(v),vis[v]=1;
            }
        }
    }
    return (dis[t]<inf);
}
void MCMF()
{   while(spfa())
    {   int i,x=t;
        maxflow+=incf[t];
        mincost+=dis[t]*incf[t];
        while(x!=s)
        {   i=pre[x];
            e[i].w-=incf[t];
            e[i^1].w+=incf[t];
            x=e[i^1].v;
        }
    }
}
int main()
{   memset(f,-1,sizeof(f));
    scanf("%d%d%d%d",&n,&m,&s,&t);
    for(int i=1;i<=m;i++)
    {   int u,v,w,c;
        scanf("%d%d%d%d",&u,&v,&w,&c);
        read(u,v,w,c);
        read(v,u,0,-c);
    }
    MCMF();
    printf("%d %d\n",maxflow,mincost); 
    return 0;
}
\text{by Rainy7}