网络流(dinic)

#include <iostream>
#include <queue>
#include <cstring>
typedef long long ll;
int n;
const int maxn=5e3+10;
struct node{
    int next,to,val;
}edge[maxn<<1];
int cnt=1,head[maxn<<1];
inline int min(int a,int b){ return a>b?b:a; }
void add(int from,int to,int val){
    edge[++cnt].to=to;
    edge[cnt].val=val;
    edge[cnt].next=head[from];
    head[from]=cnt;
}
int cur[maxn<<1],dep[maxn<<1];
int bfs(int s,int t){
    for(int i=1;i<=n;i++){ cur[i]=head[i]; }
    std::queue<int>q;q.push(s);
    memset(dep,-1,sizeof dep);
    dep[s]=0;
    while(!q.empty()){
        int temp=q.front();q.pop();
        for(int i=head[temp];i;i=edge[i].next){
            if(dep[edge[i].to]==-1&&edge[i].val){
                dep[edge[i].to]=dep[temp]+1;
                q.push(edge[i].to);
            }
        }
    }
    return dep[t];
}
ll dfs(int s,int t,int limit){
    if(s==t||!limit)return limit;
    ll ans=0;int f;
    for(int i=cur[s];i;i=edge[i].next){
        cur[s]=i;
        if(dep[edge[i].to]==dep[s]+1&&(f=dfs(edge[i].to,t,min(limit,edge[i].val)))){
            ans+=f;
            limit-=f;
            edge[i].val-=f;
            edge[i^1].val+=f;
            if(!limit)break;
        }
    }
    return ans;
}
ll dinic(int s,int t){
    ll ans=0;
    while(bfs(s,t)!=-1)
        ans+=dfs(s,t,0x3f3f3f3f);
    return ans;
}
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);std::cout.tie(0);
    int m,s,t;
    std::cin>>n>>m>>s>>t;
    for(int i=0,u,v,val;i<m;i++){
        std::cin>>u>>v>>val;
        add(u,v,val);add(v,u,0);
    }
    std::cout<<dinic(s,t);
}
View Code

 

posted @ 2021-04-19 16:03  Acception  阅读(42)  评论(0)    收藏  举报