dinic

代码来源是狼抓兔子

先跑出分层图然后流
有当前弧优化(这个和欧拉回路的操作很像?)

#include<bits/stdc++.h>
#define F(i,i0,n) for(int i=i0;i<=n;i++)
#define Ln inline 
#define ll long long
using namespace std;
inline int rd(){
    int f=0,x=0;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=1;ch=getchar();}
    while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
    return f?-x:x;
}
const int N=2e3+3,inf=1e9;
struct Id{
    int v,w,nt;
}e[N*N*6];
int p[N*N],id=1;
Ln void add(int x,int y,int z){
    e[++id]={y,z,p[x]};
    p[x]=id;
    e[++id]={x,0,p[y]};
    p[y]=id;
    e[++id]={x,z,p[y]};
    p[y]=id;
    e[++id]={y,0,p[x]};
    p[x]=id;
}
int dis[N*N],cur[N*N];
int n,m,s,t;
bool bfs(){
    memset(dis,-1,sizeof(dis));
    queue<int>q;
    q.push(s);
    dis[s]=0;
    while(!q.empty()){
        int x=q.front();q.pop();
        for(int i=p[x];i;i=e[i].nt){
            int v=e[i].v;
            if(dis[v]==-1&&e[i].w){
                dis[v]=dis[x]+1;
                q.push(v);
            }
        }
    }
    return dis[t]!=-1;
}
int dfs(int x,int sum){
    if(x==t)return sum;
    for(int i=cur[x];i&&sum;i=e[i].nt){
        cur[x]=i;
        int v=e[i].v;
        if(e[i].w&&dis[v]==dis[x]+1){
            int k=dfs(v,min(sum,e[i].w));
            if(k){
                e[i].w-=k;
                e[i^1].w+=k;
                return k;
            }
            else dis[v]=-1; 
        }
    }
    return 0;
}
int dinic(){
    int ans=0,k;
    while(bfs()){
        memcpy(cur,p,sizeof(p));
        while(k=dfs(s,inf))ans+=k;
    }
    return ans;
}
signed main(){
    n=rd(),m=rd();
    s=1,t=n*m;
    F(i,1,n){
        F(j,1,m-1){
            int x=rd();
            add((i-1)*m+j,(i-1)*m+j+1,x);
        } 
    } 
    F(i,1,n-1){
        F(j,1,m){
            int x=rd();
            add((i-1)*m+j,i*m+j,x);
        } 
    } 
    F(i,1,n-1){
        F(j,1,m-1){
            int x=rd();
            add((i-1)*m+j,i*m+j+1,x);
        } 
    } 
    cout<<dinic();
    return 0;
}
posted @ 2023-09-09 17:09  ussumer  阅读(20)  评论(0)    收藏  举报