• 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;
    }
    

    ####原题目描述:
  • 相关阅读:
    必读:Spark与kafka010整合
    6 个开源的家庭自己主动化工具 | Linux 中国
    承上 DBlink 与 SCN | 新增视图找出外部 SCN 跳变
    NetBeans使用Consolas中文乱码的解决
    IDEA community + Gradle + Gretty 调试 servlet 应用 + war包部署到tomcat
    解决ubuntu下IntelliJ IDEA无法锁定到启动器的问题
    virtualbox安装android6.0并设置分辨率为1920x1080x32
    Ubuntu安装Sqlite报错:No module named 'ConfigParser'
    Linux常用指令笔记
    解决Warning Couldn't flush user prefs: java.util.prefs.BackingStoreException: Couldn't get file lock.
  • 原文地址:https://www.cnblogs.com/Cwolf9/p/9420182.html
Copyright © 2020-2023  润新知