运输问题

又是一个裸的费用流板子,不再赘述。

看代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define inf 1e12
const int maxn=1e5+10;
int n,m,ans1,ans2;
struct wll{
    int beg[maxn],nex[maxn],to[maxn],w[maxn],cost[maxn],e;
    inline wll(){memset(beg,-1,sizeof(beg));}
    inline void add(int x,int y,int z,int c){
        nex[e]=beg[x];beg[x]=e;to[e]=y;
        w[e]=z;cost[e]=c;e++;
    }
    int dis[maxn],vis[maxn],las[maxn],ed[maxn],flow[maxn];
    queue<int>q;
    inline int spfa(){
        memset(dis,0x3f,sizeof(dis));
        memset(vis,0,sizeof(vis));
        while(!q.empty())q.pop();
        dis[0]=0;vis[0]=1;flow[0]=inf;
        las[n+m+1]=-1;q.push(0);
        while(!q.empty()){
            int x=q.front();
            q.pop();vis[x]=0;
            for(int i=beg[x];~i;i=nex[i]){
                int t=to[i];
                if(w[i]&&dis[t]>dis[x]+cost[i]){
                    dis[t]=dis[x]+cost[i];
                    las[t]=x;ed[t]=i;
                    flow[t]=min(w[i],flow[x]);
                    if(!vis[t]){
                        vis[t]=1;q.push(t);
                    }
                }
            }
        }
        return las[n+m+1]!=-1;
    }
}w1,w2;
inline int read(){
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    return x*f;
}
signed main(){
    n=read(),m=read();
    int x;
    for(int i=1;i<=n;i++){
        x=read();
        w1.add(0,i,x,0);
        w1.add(i,0,0,0);
        w2.add(0,i,x,0);
        w2.add(i,0,0,0);
    }
    for(int i=1;i<=m;i++){
        x=read();
        w1.add(i+n,n+m+1,x,0);
        w1.add(n+m+1,i+n,0,0);
        w2.add(i+n,n+m+1,x,0);
        w2.add(n+m+1,i+n,0,0);
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            x=read();
            w1.add(i,j+n,inf,x);
            w1.add(j+n,i,0,-x);
            w2.add(i,j+n,inf,-x);
            w2.add(j+n,i,0,x);
        }
    while(w1.spfa()){
        ans1+=w1.dis[n+m+1]*w1.flow[n+m+1];
        int tmp=n+m+1;
        while(tmp){
            w1.w[w1.ed[tmp]]-=w1.flow[n+m+1];
            w1.w[w1.ed[tmp]^1]+=w1.flow[n+m+1];
            tmp=w1.las[tmp];
        }
    }
    while(w2.spfa()){
        ans2-=w2.dis[n+m+1]*w2.flow[n+m+1];
        int tmp=n+m+1;
        while(tmp){
            w2.w[w2.ed[tmp]]-=w2.flow[n+m+1];
            w2.w[w2.ed[tmp]^1]+=w2.flow[n+m+1];
            tmp=w2.las[tmp];
        }
    }
    printf("%lld\n%lld\n",ans1,ans2);
    return 0;
}

就是打代码有点心累。

深深地感到自己的弱小。

posted @ 2020-04-09 22:02  syzf2222  阅读(119)  评论(0编辑  收藏  举报