Skip to content

Latest commit

 

History

History
94 lines (94 loc) · 2.58 KB

POJ2516.md

File metadata and controls

94 lines (94 loc) · 2.58 KB

K个商品是独立的,所以跑k次费用流即可

#include<cstring>
#include<queue>
#include<cstdio>
#include<iostream>
#include<vector>
using namespace std;
const int MAXN = 222;
const int INF = 0x3f3f3f3f;
#define S 0
#define T MAXN - 1
int n,m,k,dist[MAXN][MAXN][MAXN],A[MAXN][MAXN],B[MAXN][MAXN],flow[MAXN],pre[MAXN],pid[MAXN],vis[MAXN],c[MAXN];
struct EDGE{
    int to, cap, fee, rev;
    EDGE(){}
    EDGE(int _to,int _cap, int _fee, int _rev){to = _to; cap = _cap; fee =_fee; rev = _rev;}
};
vector<EDGE> G[MAXN];
void ADDEDGE(int u, int v, int cap, int fee){
    G[u].push_back(EDGE(v,cap,fee,(int)G[v].size()));
    G[v].push_back(EDGE(u,0,-fee,(int)G[u].size()-1));
}
bool spfa(){
    memset(vis,0,sizeof(vis));
    memset(c,INF,sizeof(c));
    c[S] = 0;
    pre[T] = -1;
    flow[S] = INF;
    queue<int> que;
    que.push(S);
    while(!que.empty()){
        int u = que.front();
        que.pop();
        vis[u] = false;
        for(int i = 0; i < (int)G[u].size(); i++){
            EDGE &e = G[u][i];
            if(!e.cap || c[e.to] <= c[u] + e.fee) continue;
            c[e.to] = c[u] + e.fee;
            pre[e.to] = u;
            pid[e.to] = i;
            flow[e.to] = min(flow[u],e.cap);
            if(!vis[e.to]){
                vis[e.to] = true;
                que.push(e.to);
            }
        }
    }
    return pre[T] != -1;
}
int mcmf(int kk){
    for(int i = 0; i < MAXN; i++) G[i].clear();
    int nd = 0, hv = 0;
    for(int i = 1; i <= m; i++){
        hv += B[i][kk];
        ADDEDGE(S,i,B[i][kk],0);
    }
    for(int i = 1; i <= n; i++){
        nd += A[i][kk];
        ADDEDGE(m+i,T,A[i][kk],0);
    }
    if(hv<nd) return -1;
    for(int i = 1; i <= m; i++) for(int j = 1; j <= n; j++) ADDEDGE(i,j+m,INF,dist[kk][j][i]);
    int cost = 0;
    while(spfa()){
        cost += flow[T] * c[T];
        int rt = T;
        while(rt){
            G[pre[rt]][pid[rt]].cap -= flow[T];
            G[rt][G[pre[rt]][pid[rt]].rev].cap += flow[T];
            rt = pre[rt];
        }
    }
    return cost;
}
int solve(){
    int tot = 0;
    for(int kk = 1; kk <= k; kk++){
        int cst = mcmf(kk);
        if(cst==-1) return -1;
        else tot += cst;
    }
    return tot;
}
int main(){
    while(scanf("%d %d %d",&n,&m,&k)!=EOF&&n+m+k){
        for(int i = 1; i <= n; i++) for(int j = 1; j <= k; j++) scanf("%d",&A[i][j]);
        for(int i = 1; i <= m; i++) for(int j = 1; j <= k; j++) scanf("%d",&B[i][j]);
        for(int kk = 1; kk <= k; kk++) for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) scanf("%d",&dist[kk][i][j]);
        printf("%d\n",solve());
    }
    return 0;
}