1. 程式人生 > >網路流 學習筆記 ①

網路流 學習筆記 ①

剛剛A了網路最大流,其實仔細思考網路流的過程還是挺簡單的,只是因為它的修正思路比較獨特,會讓人有點難懂,但是最大流本身還是好理解的。
先上EK的程式碼:

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=1e4+5,maxm=1e5+5;

inline int read(){
    char ch=getchar();
    int r=0,s=1;
    while(ch>57||ch<48)s=ch==45?0:s,ch=getchar();
    while(ch>=48&&ch<=57)r=r*10+ch-48,ch=getchar();
    return s?r:-r;
}

queue < int > q;
struct edge{int fa,to,nxt,f,c,rs;}e[maxm<<1];
int n,m,st,ed,cnt,ans;
int head[maxn],a[maxn],pre[maxn];

void add(int u,int v,int w){
    e[++cnt]=(edge){u,v,head[u],0,w,cnt+1},head[u]=cnt;
    e[++cnt]=(edge){v,u,head[v],0,0,cnt-1},head[v]=cnt;
    return;
}

bool Get_maxf(){
    int u,v;
    memset(a,0,sizeof(a));
    while(q.size())q.pop();
    q.push(st),pre[st]=0,a[st]=inf;
    while(q.size()){
        u=q.front(),q.pop();
        for(int i=head[u];i;i=e[i].nxt){
            v=e[i].to;
            if(!a[v]&&e[i].c>e[i].f){
                a[v]=min(a[u],e[i].c-e[i].f);
                pre[v]=i;
                q.push(v);
            }
        }
        if(a[ed])break;
    }
    if(!a[ed])return 0;
    for(int i=ed;i!=st;i=e[pre[i]].fa){
        e[pre[i]].f+=a[ed];
        e[e[pre[i]].rs].f-=a[ed];
    }
    ans+=a[ed];
    return 1;
}
          
int main(){
    n=read(),m=read(),st=read(),ed=read();
    for(int i=1,x,y,z;i<=m;++i)x=read(),y=read(),z=read(),add(x,y,z);
    while(Get_maxf());
    printf("%d\n",ans);
    return 0;
}

然後我去咕下Dinic