zoukankan      html  css  js  c++  java
  • POJ2516费用流

    (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦

    目录

    题意:传送门


    ####AC代码:
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <cstdlib>
    #include <string>
    #include <bitset>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <algorithm>
    #include <sstream>
    #include <stack>
    #include <iomanip>
    using namespace std;
    typedef long long LL;
    
    const int MAXN = 605;
    const int MAXE = 4e5 + 7;
    const int INF = 0x3f3f3f3f;
    struct MCMF {
        int S, T;//源点,汇点
        int tot, n;
        int st, en, maxflow, mincost;
        bool vis[MAXN];
        int head[MAXN], cur[MAXN], dis[MAXN];
        int roade[MAXN], roadv[MAXN], rsz; //用于打印路径
        queue <int> Q;
        struct Edge {
            int v, cap, cost, nxt, flow;
            Edge() {}
            Edge(int a, int b, int c, int d) {
                v = a, cap = b, cost = c, nxt = d, flow = 0;
            }
        } E[MAXE], SE[MAXE];
        void init(int _n) {
            n = _n, tot = 0;
            for(int i = 0; i <= n; i++) head[i] = -1;
        }
        void add_edge(int u, int v, int cap, int cost) {
            E[tot] = Edge(v, cap, cost, head[u]);
            head[u] = tot++;
            E[tot] = Edge(u, 0, -cost, head[v]);
            head[v] = tot++;
        }
        bool adjust() {
            int v, min = INF;
            for(int i = 0; i <= n; i++) {
                if(!vis[i]) continue;
                for(int j = head[i]; ~j; j = E[j].nxt) {
                    v = E[j].v;
                    if(E[j].cap - E[j].flow) {
                        if(!vis[v] && dis[v] - dis[i] + E[j].cost < min) {
                            min = dis[v] - dis[i] + E[j].cost;
                        }
                    }
                }
            }
            if(min == INF) return false;
            for(int i = 0; i <= n; i++) {
                if(vis[i]) {
                    cur[i] = head[i];
                    vis[i] = false;
                    dis[i] += min;
                }
            }
            return true;
        }
        int augment(int i, int flow) {
            if(i == en) {
                mincost += dis[st] * flow;
                maxflow += flow;
                return flow;
            }
            vis[i] = true;
            for(int j = cur[i]; j != -1; j = E[j].nxt) {
                int v = E[j].v;
                if(E[j].cap == E[j].flow) continue;
                if(vis[v] || dis[v] + E[j].cost != dis[i]) continue;
                int delta = augment(v, std::min(flow, E[j].cap - E[j].flow));
                if(delta) {
                    E[j].flow += delta;
                    E[j ^ 1].flow -= delta;
                    cur[i] = j;
                    return delta;
                }
            }
            return 0;
        }
        void spfa() {
            int u, v;
            for(int i = 0; i <= n; i++) {
                vis[i] = false;
                dis[i] = INF;
            }
            Q.push(st);
            dis[st] = 0;
            vis[st] = true;
            while(!Q.empty()) {
                u = Q.front(), Q.pop();
                vis[u] = false;
                for(int i = head[u]; ~i; i = E[i].nxt) {
                    v = E[i].v;
                    if(E[i].cap == E[i].flow || dis[v] <= dis[u] + E[i].cost) continue;
                    dis[v] = dis[u] + E[i].cost;
                    if(!vis[v]) {
                        vis[v] = true;
                        Q.push(v);
                    }
                }
            }
            for(int i = 0; i <= n; i++) {
                dis[i] = dis[en] - dis[i];
            }
        }
        int zkw_flow(int s, int t,int Sum) {
            st = s, en = t;
            spfa();
            mincost = maxflow = 0;
            for(int i = 0; i <= n; i++) {
                vis[i] = false;
                cur[i] = head[i];
            }
            do {
                while(augment(st, INF)) {
                    memset(vis, false, n * sizeof(bool));
                }
            } while(adjust());
            if(maxflow!=Sum)return -1;
            return mincost;
        }
    }zkw;
    //u v 流量 费用
    const int N = 55;
    inline int ab(int x){return x<0?-x:x;}
    int vs,vt;
    int n,m,p;
    int ar[N][N],br[N][N],cr[N][N];
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("E://ADpan//in.in", "r", stdin);
        //freopen("E://ADpan//out.out", "w", stdout);  
    #endif
      while(~scanf("%d%d%d",&n,&m,&p)&&(n+m+p)){
        vs=n+m+1;vt=n+m+2;
        //建p次图
        //1-n客户,n-n+m仓库
        for(int i=1;i<=n;++i){
          for(int j=0,x;j<p;++j){
            scanf("%d",&ar[i][j]);//客户
          }
        }
        for(int i=1;i<=m;++i){
          for(int j=0,x;j<p;++j){
            scanf("%d",&br[i][j]);//仓库
          }
        }
        int ans=0,flag=1;
        for(int h=0;h<p;++h){
          zkw.init(n+m+2);
          int sum=0;
          for(int i=1;i<=n;++i){
            zkw.add_edge(i,vt,ar[i][h],0);
            sum+=ar[i][h];
          }
          for(int i=1;i<=m;++i){
            zkw.add_edge(vs,i+n,br[i][h],0);
          }
          for(int i=1;i<=n;++i){
            for(int j=1;j<=m;++j){
              int x;scanf("%d",&x);
              zkw.add_edge(j+n,i,INF,x);
            }
          }
          int tmp = zkw.zkw_flow(vs,vt,sum);
          if(tmp==-1)flag=0;
          ans+=tmp;
        }
        if(flag==0)printf("-1
    ");
        else printf("%d
    ", ans);
      }
      return 0;
    }
    

    ####原题目描述:
  • 相关阅读:
    hdu acm 2844 Coins 解题报告
    hdu 1963 Investment 解题报告
    codeforces 454B. Little Pony and Sort by Shift 解题报告
    广大暑假训练1 E题 Paid Roads(poj 3411) 解题报告
    hdu acm 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活
    hdu acm 1114 Piggy-Bank 解题报告
    poj 2531 Network Saboteur 解题报告
    数据库范式
    ngnix 配置CI框架 与 CI的简单使用
    Vundle的安装
  • 原文地址:https://www.cnblogs.com/Cwolf9/p/9420182.html
Copyright © 2011-2022 走看看