網路流最大流

lyrrr發表於2024-10-30

EK

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long

const int maxn = 5000 + 10, inf=0x3f3f3f3f3f3f3f3f;

int tot=1,head[maxn],n,m,s,t,dis[maxn*4],pre[maxn*4],ans=0,flg[maxn][maxn];
bool vis[maxn*4];
struct node{
    int nxt,to,val;
}e[maxn*4];

void add_edge(int u,int v,int w){
    e[++tot].to=v;e[tot].nxt=head[u];head[u]=tot;e[tot].val=w;
    e[++tot].to=u;e[tot].nxt=head[v];head[v]=tot;e[tot].val=0;
}

inline int bfs(){
    for(int i=1;i<=n;i++)vis[i]=0;
    queue<int>q;
    q.push(s);
    vis[s]=1;dis[s]=inf;
    while(!q.empty()){
        int x=q.front();q.pop();
        for(int i=head[x];i;i=e[i].nxt){
            if(e[i].val==0)continue;//rem>0
            int v=e[i].to;
            if(vis[v])continue;//unvisited edge
            dis[v]=min(dis[x],e[i].val);//get min capacity
            pre[v]=i;//the edge before i
            q.push(v);
            vis[v]=1;
            if(v==t)return 1;//find one extension road
        }
    }
    return 0;
}
inline void update(){
    int x=t;
    while(x!=s){
        int v=pre[x];
        e[v].val-=dis[t];
        e[v^1].val+=dis[t];
        x=e[v^1].to;
    }
    ans+=dis[t];
}

signed main(){
    ios::sync_with_stdio(false);cin.tie(nullptr); 

    cin>>n>>m>>s>>t;
    for(int i=1;i<=m;i++){
        int u,v,w;cin>>u>>v>>w;
        if(flg[u][v])e[flg[u][v]-1].val+=w;
        else add_edge(u,v,w),flg[u][v]=tot;
    }
    while(bfs()!=0){
        update();
    }
    cout<<ans<<endl;
    return 0;
    
}

Dinic

相關文章