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

    也当作模板吧。。

  • 相关阅读:
    网页加速的14条优化法则 网站开发与优化
    .NET在后置代码中输入JS提示语句(背景不会变白)
    C语言变量声明内存分配
    SQL Server Hosting Toolkit
    An established connection was aborted by the software in your host machine
    C语言程序设计 2009春季考试时间和地点
    C语言程序设计 函数递归调用示例
    让.Net 程序脱离.net framework框架运行
    C语言程序设计 答疑安排(2009春季 110周) 有变动
    软件测试技术,软件项目管理 实验时间安排 2009春季
  • 原文地址:https://www.cnblogs.com/louzhang/p/2634457.html
Copyright © 2011-2022 走看看