zoukankan      html  css  js  c++  java
  • poj_2516,最小费用最大流

    http://poj.org/problem?id=2516

    参考这篇博客写的。。。

    http://www.cppblog.com/Icyflame/archive/2009/06/30/88941.html

    这几天算是被网络流整死了,算法太复杂了,理解起来确实是难。。

    2516
    #include<cstdio>
    #include<cstring>
    
    const int inf = 10000000;
    const int maxn = 110;
    struct Edge{
        int u, v, w, c, next;
    }e[maxn * maxn * 4];
    int head[maxn], index;
    void init_edge(){
        memset(head, -1, sizeof head);
        index = 0;
    }
    void _add_edge(int u, int v, int w, int c){
        e[index].u = u, e[index].v = v;
        e[index].w = w, e[index].c = c;
        e[index].next = head[u];
        head[u] = index ++;
    }
    void add_edge(int u, int v, int w, int c){
        _add_edge(u, v, w, c);
        _add_edge(v, u, -w, 0);
    }
    int q[1000000 + 10];
    int visit[maxn];
    int dist[maxn];
    int pre[maxn];
    int s, t, n;
    bool spfa(){
        int qs = 0, qe = 0;
        memset(visit, 0, sizeof visit);
        memset(pre, -1, sizeof pre);
        for(int i = s; i <= t; i ++) dist[i] = inf;
        q[qe++] = s;
        visit[s] = 1;
        dist[s] = 0;
        while(qs < qe){
            int now = q[qs++];
            visit[now] = 0;
            for(int i = head[now]; i + 1; i = e[i].next){
                int v = e[i].v;
                if(!e[i].c) continue;
                if(dist[v] == inf || dist[now] + e[i].w < dist[v]){
                    dist[v] = dist[now] + e[i].w;
                    pre[v] = i;
                    if(!visit[v]){
                        visit[v] = 1;
                        q[qe++] = v;
                    }
                }
            }
        }
        return dist[t] != inf;
    }
    int min_cost(){
        int cost = 0;
        while(spfa()){
            int flow = inf;
            for(int i = pre[t]; i != -1; i = pre[e[i].u])
              if(flow > e[i].c) flow = e[i].c;
            for(int i = pre[t]; i != -1; i = pre[e[i].u]){
                e[i].c -= flow;
                e[i^1].c += flow;
            }
            cost += flow * dist[t];
        }
        return cost;
    }
    int N, M, K;
    int need[maxn][maxn];
    int supply[maxn][maxn];
    int m[maxn][maxn][maxn];
    int main(){
        while(scanf("%d%d%d", &N, &M, &K), N||M||K){
            for(int i = 1; i <= N; i ++){
                for(int j  = 1; j <= K; j ++){
                    int a;
                    scanf("%d", &a);
                    need[i][j] = a;
                }
            }
            for(int i = 1; i <= M; i ++){
                for(int j = 1; j <= K; j ++){
                   int a;
                   scanf("%d", &a);
                   supply[i][j] = a;
                }
            }
            for(int i = 1; i <= K; i ++){
                for(int j = 1; j <= N; j ++){
                    for(int k = 1; k <= M; k ++){
                        int a;
                        scanf("%d", &a);
                        m[i][j][k] = a;
                    }
                }
            }
            n = N + M;
            s = 0, t = n + 1;
            int ans = 0;
            for(int k = 1; k <= K; k ++){
                init_edge();
                for(int i = 1; i <= M; i ++){
                    add_edge(s, i, 0, supply[i][k]);
                }
                for(int i = 1; i <= M; i ++){
                    for(int j = 1; j <= N; j ++){
                        add_edge(i, j + M, m[k][j][i], inf);
                    }
                }
                for(int i = 1; i <= N; i ++){
                    add_edge(i + M, t, 0, need[i][k]);
                }
                ans += min_cost();
                bool flag = 0;
                for(int i = 1 + M; i <= N + M; i ++){
                    for(int j = head[i]; j + 1; j = e[j].next){
                        int v = e[j].v;
                        if(v == t && e[j].c > 0){
                            flag = true;
                            break;
                        }
                    }
                    if(flag) break;
                }
                if(flag){
                    ans = -1;
                    break;
                }
            }
            printf("%d\n", ans);
        }
        return 0;
    }

    也当作模板吧。。

  • 相关阅读:
    记一次vue.js用 http.post 前端传json到后台用javabean接收的坑
    springboot1.5.x 测试sample
    sqlserver 查询表缺失索引
    Docker swarm上线的一些问题
    数据库日志文件压缩
    Docker 挂载
    单播广播和多播
    导入数据库表后某些字段的精度为0
    Source Qualifiter组件中Sql Query属性的脚本返回结果集的列数大于组件定义的数量
    distinct和order by冲突
  • 原文地址:https://www.cnblogs.com/louzhang/p/2634457.html
Copyright © 2011-2022 走看看