1. 程式人生 > >【網路流24題】運輸問題(最小費用最大流)

【網路流24題】運輸問題(最小費用最大流)

題意

W 公司有 mm 個倉庫和 nn 個零售商店。第 ii 個倉庫有 aia_i​​ 個單位的貨物;第 jj 個零售商店需要 bjb_j​​ 個單位的貨物。貨物供需平衡,即i=1mai=j=1nbj\sum\limits_{i = 1} ^ m a_i = \sum\limits_{j = 1} ^ n b_j ​​​​。從第 ii 個倉庫運送每單位貨物到第 jj 個零售商店的費用為cijc_{ij}​​。試設計一個將倉庫中所有貨物運送到零售商店的運輸方案,使總運輸費用最少。

題解

最小費用最大流

程式碼

普通的最小費用最大流

#include <bits/stdc++.h>
using namespace std;
const int nmax = 10000;
const int INF = 0x3f3f3f3f;
typedef int valtype;
struct MCMF{
    valtype final_flow,final_cost;
    int tot,S,T;
    bool inque[nmax];
    int head[nmax], pre_edge[nmax],pre_index[nmax];
    valtype add_flow[nmax], dis[nmax];
    struct
edge{int to,nxt;valtype cap,flow,cost;}e[nmax<<1]; void init(int S, int T){ memset(head,-1,sizeof head); tot = 0; this->S = S, this->T = T; } void add_edge(int u, int v, valtype cap, valtype cost){ e[tot].to = v, e[tot].nxt = head[u], e[tot].flow =
0, e[tot].cap = cap, e[tot].cost = cost, head[u] = tot++; e[tot].to = u, e[tot].nxt = head[v], e[tot].flow = 0, e[tot].cap = 0, e[tot].cost = -cost, head[v] = tot++; } bool spfa(){ for(int i = S;i<=T;++i) inque[i] = false, dis[i] = i == S?0:INF; queue<int> q; q.push(S), inque[S] = true, add_flow[S] = INF; while(!q.empty()){ int u = q.front(); q.pop(); inque[u] = false; for(int i = head[u];i!=-1;i=e[i].nxt){ int v = e[i].to; if(e[i].cap > e[i].flow && dis[u] + e[i].cost < dis[v]){ dis[v] = dis[u] + e[i].cost, pre_edge[v] = i, pre_index[v] = u; add_flow[v] = min(add_flow[u],e[i].cap - e[i].flow); if(!inque[v]) q.push(v),inque[v] = true; } } } return dis[T] != INF; } void mincost_mxflow() { final_cost = final_flow = 0; while(spfa()){ final_flow += add_flow[T]; final_cost += add_flow[T] * dis[T]; int now = T; while(now != S){ e[pre_edge[now]].flow += add_flow[T]; e[pre_edge[now]^1].flow -= add_flow[T]; now = pre_index[now]; } } } }mcmf; int n, m; int a[105], b[105]; int cost[105][105]; int main() { scanf("%d %d", &n, &m); int s = 0, t = n + m + 1, tmp; mcmf.init(s, t); for(int i = 1; i <= n; ++i) { scanf("%d", &a[i]); mcmf.add_edge(s, i, a[i], 0); } for(int i = 1; i <= m; ++i) { scanf("%d", &b[i]); mcmf.add_edge(n + i, t, b[i], 0); } for(int i = 1; i <= n; ++i) { for(int j = 1; j <= m; ++j) { scanf("%d", &cost[i][j]); mcmf.add_edge(i, j + n, a[i], cost[i][j]); } } mcmf.mincost_mxflow(); printf("%d\n", mcmf.final_cost); mcmf.init(s, t); for(int i = 1; i <= n; ++i) mcmf.add_edge(s, i, a[i], 0); for(int i = 1; i <= m; ++i) mcmf.add_edge(n + i, t, b[i], 0); for(int i = 1; i <= n; ++i) { for(int j = 1; j <= m; ++j) { mcmf.add_edge(i, j + n, a[i], -cost[i][j]); } } mcmf.mincost_mxflow(); printf("%d\n", -mcmf.final_cost); }

zkw最小費用最大流

#include <bits/stdc++.h>
using namespace std;
const int nmax = 10000;
const int INF = 0x3f3f3f3f;
typedef int valtype;
struct zkwflow {
    struct edge {
        valtype cost, cap;
        int nxt, re, to;
    }e[nmax];
    int head[nmax], tot, vis[nmax], s, t;
    valtype ans, cost, maxflow;
    void init(int s, int t) {
        memset(head, -1, sizeof(head));
        tot = 0;
        ans = cost = maxflow = 0;
        this->s = s, this->t = t;
    }
    void add_edge(int u, int v, valtype cap, valtype cost) {
        e[tot].to = v;
        e[tot].cap = cap;
        e[tot].cost = cost;
        e[tot].re = tot + 1;
        e[tot].nxt = head[u];
        head[u] = tot++;
        e[tot].to = u;
        e[tot].cap = 0;
        e[tot].cost = -cost;
        e[tot].re = tot - 1;
        e[tot].nxt = head[v];
        head[v] = tot++;
    }
    valtype aug(int u, valtype f) {
        if(u == t) {
            ans += cost * f;
            maxflow += f;
            return f;
        }
//        printf("debug %d %d\n", u, f);
        vis[u] = 1;
        valtype tmp = f;
        for(int i = head[u]; i != -1; i = e[i].nxt)
            if(e[i].cap && !e[i].cost && !vis[e[i].to]) {
                valtype delta = aug(e[i].to, tmp < e[i].cap ? tmp : e[i].cap);
                e[i].cap -= delta;
                e[e[i].re].cap += delta;
                tmp -= delta;
                if(!tmp) return f;
            }
        return f - tmp;
    }
    bool modlabel(int n) {
        valtype delta = INF;
        for(int u = 1; u <= n; u++)
            if(vis[u])
                for(int i = head[u]; i != -1; i = e[i].nxt)
                    if(e[i].cap && !vis[e[i].to] && e[i].cost < delta) delta = e[i].cost;
        if(delta == INF) return false;
        for(int u = 1; u <= n; u++)
            if(vis[u])
                for(int i = head[u]; i != -1; i = e[i].nxt)
                    e[i].cost -= delta, e[e[i].re].cost += delta;
        cost += delta;
        return true;
    }
    valtype costflow() {
        do {
            do {
                memset(vis, 0, sizeof(vis));
            }while(aug(s, INF));
        }while(modlabel(t));
        return ans;
    }
}zkw;
int n, m;
int a[105], b[105];
int cost[105][105];
int main() {
    scanf("%d %d", &n, &m);
    int s = n + m + 1, t = n + m + 2;
    zkw.init(s, t);
    for(int i = 1; i <= n; ++i) {
        scanf("%d", &a[i]);
        zkw.add_edge(s, i, a[i], 0);
    }
    for(int i = 1; i <= m; ++i) {
        scanf("%d", &b[i]);
        zkw.add_edge(n + i, t, b[i],  0);
    }
    for(int i = 1; i <= n; ++i) {
        for(int j = 1; j <= m; ++j) {
            scanf("%d", &cost[i][j]);
            zkw.add_edge(i, j + n, a[i], cost[i][j]);
        }
    }
    zkw.costflow();
    printf("%d\n", zkw.ans);
    zkw.init(s, t);
    for(int i = 1; i <= n; ++i)
        zkw.add_edge(s, i, a[i], 0);
    for(int i = 1; i <= m; ++i)
        zkw.add_edge(n + i, t, b[i], 0);
    for
            
           

相關推薦

網路24運輸問題費用

題意 W 公司有 mmm 個倉庫和 nnn 個零售商店。第 iii 個倉庫有 aia_iai​​​ 個單位的貨物;第 jjj 個零售商店需要 bjb_jbj​​​ 個單位的貨物。貨物供需平衡,即∑i=1mai=∑j=1nbj​​\sum\limits_{i =

網絡24運輸問題費用網絡費用流量

size tle 輸出 main pre algorithm 流量 out text 【網絡流24題】運輸問題 2014年3月7日1,6360 題目描述 Description W 公司有m個倉庫和n 個零售商店。第i 個倉庫有ai 個單位的貨物;第j

網絡24運輸問題費用

return 。。 size define max freopen markdown %d true 【網絡流24題】運輸問題(費用流) 題面 Cogs 題解 大水題。。。 源點向倉庫連,容量為貨物量,費用為0 倉庫向商店連,容量INF,費用題目給出來了 商店向匯點連,容量

網絡24魔術球問題 二分答案+路徑覆蓋

cnblogs for getchar() str logs math 等於 active rip Description 假設有n根柱子,現要按下述規則在這n根柱子中依次放入編號為1,2,3,...的球。 (1)每次只能在某根柱子的最上面放球。 (2)在同一根柱子

網路24餐巾計劃費用

題意 一個餐廳在相繼的 nnn 天裡,每天需用的餐巾數不盡相同。假設第 iii 天需要 rir_iri​​​ 塊餐巾。餐廳可以購買新的餐巾,每塊餐巾的費用為 PPP 分;或者把舊餐巾送到快洗部,洗一塊需 MMM天,其費用為 FFF 分;或者送到慢洗部,洗一塊需

2018.10.22網路24洛谷P2770LOJ6122航空路線問題費用

洛谷傳送門 解析: 調了半天最後發現費用流部分一個小細節跪了。。。 心態爆炸。。。問題不大 思路: 首先我們直接找出兩條沒有重複節點的路徑,一條正著輸出一條倒著輸出就行了。 找的話考慮網路流。我們將每個點拆點成兩個ai,bia_i,b_iai​,bi​,為保

網路24 No.10 餐巾計劃問題 線性規劃網路優化 費用

【題意】   一個餐廳在相繼的 N 天裡, 每天需用的餐巾數不盡相同。 假設第 i 天需要 ri 塊餐巾(i=1,2,…, N)。 餐廳可以購買新的餐巾,每塊餐巾的費用為 p 分;或者把舊餐巾送到快洗部,洗一塊需 m 天,其費用為 f分;或者送到慢洗部, 洗一塊需 n 天(n>m),其費用為 s<

洛谷4016 負載平衡問題網路24費用

前言 網路流24題還是要寫一下。 Solution 我們先來研究一下這個題目是個什麼東西: 每一個點有可能比平均數多,也有可能少,然後你就發現相當於是我們建了兩個超級源點和超級匯點,然後從這兩個點去分和流入。 然後對於這個環就可以直接建環(注意建邊的時候的一些細節操作) 跑一邊費用流就好了。 #inc

網路24火星探險問題費用

題面 題解 如果不考慮標本的採集 那麼,很容易的 直接相鄰點連邊就行了 現在,因為要考慮標本數最多 所以每個點要額外考慮一個標本 但是標本又只能採集一次 所以,拆點,標本就額外的連一條容量1費用1的邊, 表示可以採集一次, 因為採集過之後

網路24試題庫二分圖+

傳送門     試題庫 I think     點集x,y分別放置試題與型別。源點向x集點連容量為1的邊,x集點向y中其所屬型別連容量為1的邊,y集點向T連容量為所需量的邊,求解最大流若等於總題數

網路 24 方格取數二分圖的點權獨立集

題意 在一個有 m×nm \times nm×n個方格的棋盤中,每個方格中有一個正整數。 現要從方格中取數,使任意 222 個數所在方格沒有公共邊,且取出的數的總和最大。試設計一個滿足要求的取數演算法。 題解 題目要求不相鄰,可以轉換為最大獨立集,又由於點權不全

網絡24魔術球問題不相交路徑覆蓋

define sam 十分 def sizeof name ++ res align 【網絡流24題】魔術球問題 2014年3月7日3,5344 Description 假設有n根柱子,現要按下述規則在這n根柱子中依次放入編號為1,2,3,4的球。(1)每次只能在

網絡24二分圖點權獨立集方格取數問題

程序 最大獨立集 取數 ron align desc 表示 就是 證明 Description 在一個有m*n 個方格的棋盤中,每個方格中有一個正整數。現要從方格中取數,使任意2 個數所在方格沒有公共邊,且取出的數的總和最大。試設計一個滿足要求的取數算法。編程任務:對於給

網絡24數字梯形問題費用大權不相交路徑

output 提示 正整數 cti 移動 block 完全 amp 方向 1913 數字梯形問題 時間限制: 2 s 空間限制: 256000 KB 題目等級 : 大師 Master

網絡24星際轉移問題網絡判定

log ima 網絡 http alt 最大流 星際 網絡流24題 ges 然後判斷什麽時候流量到達k就可以了。【網絡流24題】星際轉移問題(最大流)(網絡判定)

網絡24騎士共存問題

itl 求一個 src 最大 tle font put 計算 國際 【codevs1922】騎士共存問題 題目描述 Description 在一個n*n個方格的國際象棋棋盤上,馬(騎士)可以攻擊的棋盤方格如圖所示。棋盤上某些方格設置了障礙,騎士不

網絡24深海機器人問題費用

排列 bold 起點 給定 text 限定 科學 cnblogs 必須 1917 深海機器人問題 題目描述 Description 深海資源考察探險隊的潛艇將到達深海的海底進行科學考察。潛艇內有多個深海機器

網絡24餐巾計劃問題費用

open pre ++i 需求 http += cst efi pty 【網絡流24題】餐巾計劃問題(最小費用最大流) 題面 COGS 洛谷上的數據範圍更大,而且要開longlong 題解 餐巾的來源分為兩種: ①新買的 ②舊的拿去洗 所以,兩種情況分別建圖 先考慮第一種

網絡24太空飛行計劃問題網絡

string include nic body push void 如何 ems read 【網絡流24題】太空飛行計劃問題(網絡流) 題面 Cogs 題解 先假設一開始拿下所有的實驗 現在要做的也就是讓減去的所有收益最少 所以,現在考慮如何求減去的最少收益 每個實驗是兩種

網絡24魔術球問題

names -m 枚舉 ble 因此 efi ron += sin 【網絡流24題】魔術球問題(最大流) 題面 Cogs 題解 是不是像極了最小路徑覆蓋? 因此,我們枚舉放到哪一個球(也可以二分) 然後類似於最小路徑覆蓋的連邊 因為一根柱子對應一個路徑的覆蓋 所以,提前預處