运输问题

https://loj.ac/problem/6011

最大费用最大流

最小费用最大流

#include <bits/stdc++.h>
using namespace std;
const int maxn = 300;
const int inf = 0x3f3f3f3f;
int n,m;
int ck(int x){
    return x;
}
int ls(int x){
    return m+x;
}
int head[maxn];
int tot =0;
struct edge{
    int v,nex,w,c;
}e[maxn*maxn];
void addedge(int u,int v,int w,int c){
    e[tot] = (edge){v,head[u],w,c};
    head[u] = tot++;
    e[tot] = (edge){u,head[v],0,-c};
    head[v] = tot++;
}
int vis[maxn];
int dis[maxn];
int pre[maxn];
bool spfa(int S,int T){
    memset(dis,0x3f,sizeof(dis));
    memset(vis,0,sizeof(vis));
    queue<int> q;
    vis[S] = 1;
    q.push(S);
    dis[S] = 0;
    while(!q.empty()){
        int now = q.front();
        q.pop();
        vis[now] = 0;
        for(int i=head[now];i!=-1;i=e[i].nex){
            int w = e[i].w;
            int c = e[i].c;
            int v = e[i].v;
            if(w>0 && dis[v]>dis[now]+c){
                dis[v] = dis[now]+c;
                pre[v] = i;
                if(vis[v]==0){
                    vis[v] = 1;
                    q.push(v);
                }
            }
        }
    }
    return dis[T]==0x3f3f3f3f?false:true;
}
int ed(int S,int T,int &maxflow){
    int ret = 0;
    int flow = 0x3f3f3f3f;
    int p;
    for(int i=T;i!=S;i=e[p^1].v){
        p = pre[i];
        flow = min(flow,e[p].w);
    }
    for(int i=T;i!=S;i=e[p^1].v){
        p = pre[i];
        ret+=flow*e[p].c;
        e[p].w-=flow;
        e[p^1].w+=flow;
    }
    maxflow+=flow;
    return ret;
}
void solve(int S,int T,int k){
    int maxflow = 0;
    int ans = 0;
    while(spfa(S,T)){
        ans+=ed(S,T,maxflow);
    }
    printf("%d\n",ans*k);
}
int aa[maxn],bb[maxn],cc[maxn][maxn];
void solve2(int S,int T){
    memset(head,-1,sizeof(head));
    tot = 0;
    for(int i=1;i<=m;i++){
        int t = aa[i];

        addedge(S,ck(i),t,0);
    }
    for(int i=1;i<=n;i++){
        int t=bb[i];
        addedge(ls(i),T,t,0);
    }
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            int t=cc[i][j];
            addedge(ck(i),ls(j),inf,-t);
        }
    }
    solve(S,T,-1);
}
int main()
{

    memset(head,-1,sizeof(head));
    scanf("%d%d",&m,&n);
    int S = 0;
    int T = m+n+1;
    for(int i=1;i<=m;i++){
        int t;
        scanf("%d",&t);
        aa[i] = t;
        addedge(S,ck(i),t,0);
    }
    for(int i=1;i<=n;i++){
        int t;scanf("%d",&t);
        bb[i] = t;
        addedge(ls(i),T,t,0);
    }
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            int t;
            scanf("%d",&t);
            cc[i][j] = t;
            addedge(ck(i),ls(j),inf,t);
        }
    }
    solve(S,T,1);
    solve2(S,T);
    return 0;
}

  

posted @ 2018-03-28 22:20  tjucxz  阅读(141)  评论(0编辑  收藏  举报