码迷,mamicode.com
首页 > 其他好文 > 详细

[Luogu] 运输问题 -- 00

时间:2018-01-06 14:18:00      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:问题   line   log   queue   spfa   oid   pos   blank   define   

https://www.luogu.org/problemnew/show/4015

#include <bits/stdc++.h>

#define gc getchar()

using namespace std;
const int N = 110;
const int oo = 999999999;

int n, m, S, T, now;
int head[N], dis[N], C[N][N], A[N], B[N], pre[N];
bool vis[N * N];
struct Node{int u, v, cost, flow, nxt;} G[(N * N) << 1], E[(N * N) << 1];
queue <int> Q;

inline int read(){
    int x = 0; char c = gc;
    while(c < 0 || c > 9) c = gc;
    while(c >= 0 && c <= 9) x = x * 10 + c - 0, c = gc;
    return x;
}

inline void add(int u, int v, int flow, int cost){
    G[now].u = u; G[now].v = v; G[now].flow = flow; G[now].cost = cost;
    G[now].nxt = head[u]; head[u] = now ++;
}

inline void build_G(){
    for(int i = 1; i <= n; i ++) add(S, i, oo, 0), add(i, S, 0, 0);
    for(int i = 1; i <= n; i ++)
        for(int j = 1; j <= m; j ++)
            add(i, n + j, A[i], C[i][j]), add(n + j, i, 0, - C[i][j]);
    for(int i = 1; i <= m; i ++) add(n + i, T, B[i], 0), add(T, n + i, 0, 0);
    for(int i = 0; i <= now; i ++){
        E[i].u = G[i].u; E[i].v = G[i].v; E[i].nxt = G[i].nxt;
        E[i].cost = - G[i].cost; E[i].flow = G[i].flow;
    }
}

inline bool spfa(int start, int endd){
    for(int i = S; i <= T; i ++) vis[i] = 0, dis[i] = oo;
    dis[start] = 0;
    Q.push(start);
    while(!Q.empty()){
        int topp = Q.front();
        Q.pop(); vis[topp] = 0;
        for(int i = head[topp]; ~ i; i = G[i].nxt){
            int v = G[i].v;
            if(dis[v] > dis[topp] + G[i].cost && G[i].flow > 0){
                dis[v] = dis[topp] + G[i].cost;
                pre[v] = i;
                if(!vis[v]) vis[v] = 1, Q.push(v);
            }
        }
    }
    return dis[endd] != oo;
}

inline void Mfmc(int & Cost){
    while(spfa(S, T)){
        int endd = T, Now;
        int min_f = oo;
        while(1) {
            Now = pre[endd];
            min_f = min(min_f, G[Now].flow);
            if(G[Now].u == S) break;
            endd = G[Now].u;
        }
        Cost += dis[T] * min_f;
        endd = T;
        while(1){
            Now = pre[endd];
            G[Now].flow -= min_f;
            G[Now ^ 1].flow += min_f;
            if(G[Now].u == S) break;
            endd = G[Now].u;
        }
    }
}

int main()
{
    n = read(); m = read(); T = n + m + 1;
    for(int i = S; i <= T; i ++) head[i] = -1;
    for(int i = 1; i <= n; i ++) A[i] = read();
    for(int i = 1; i <= m; i ++) B[i] = read();
    for(int i = 1; i <= n; i ++) for(int j = 1; j <= m; j ++) C[i][j] = read();
    build_G();
    int Min_cost(0);
    Mfmc(Min_cost);
    cout << Min_cost << endl;
    for(int i = 0; i <= now; i ++){
        G[i].u = E[i].u; G[i].v = E[i].v; G[i].nxt = E[i].nxt;
        G[i].cost = E[i].cost; G[i].flow = E[i].flow;
    }
    Min_cost = 0;
    Mfmc(Min_cost);
    cout << - Min_cost;
    return 0;
}
/*
2 3
220 280
170 120 210
77 39 105
150 186 122
*/

 

[Luogu] 运输问题 -- 00

标签:问题   line   log   queue   spfa   oid   pos   blank   define   

原文地址:https://www.cnblogs.com/shandongs1/p/8213715.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!