zoukankan      html  css  js  c++  java
  • poj2516

    /***************************************************************\
    * Author: Hu Wenbiao
    * Created Time: Sat 02 Oct 2010 08:31:09 PM CST
    * File Name: main.cpp
    * Description: 最小费用最大流。对每种货物用一次mcmf。
    \***************************************************************/
    //*========================*Head File*========================*\\
    
    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<queue>
    /*----------------------*Global Variable*----------------------*/
    
    #define maxn 105
    #define inf 0x3f3f3f3f
    struct edge {
        int v, w, f, c, next;
    } e[5100];
    int vst[maxn], dis[maxn], start[maxn], p[maxn];
    int tot, N, M, K, flow_sum, ans, need[60][60], supply[60][60], cost,
        good_sum;
    
    //*=======================*Main Program*=======================*//
    using namespace std;
    
    void _add(int v, int w, int f, int c)
    {
        e[tot].v = v;
        e[tot].w = w;
        e[tot].f = f;
        e[tot].c = c;
        e[tot].next = start[v];
        start[v] = tot++;
    }
    
    void add(int v, int w, int f, int c)
    {
        _add(v, w, f, c);
        _add(w, v, 0, -c);
    }
    
    bool spfa(int s, int t, int n)
    {
        int v, w;
        queue < int >q;
        for (int i = 0; i < n; i++) {
    	p[i] = -1;;
    	vst[i] = 0;
    	dis[i] = inf;
        }
        vst[s] = 1;
        dis[s] = 0;
        q.push(s);
    
        while (!q.empty()) {
    	v = q.front();
    	q.pop();
    	vst[v] = false;
    	for (int i = start[v]; i != -1; i = e[i].next) {
    	    if (e[i].f) {
    		w = e[i].w;
    		if (dis[w] > dis[v] + e[i].c) {
    		    dis[w] = dis[v] + e[i].c;
    		    p[w] = i;
    		    if (!vst[w]) {
    			vst[w] = true;
    			q.push(w);
    		    }
    		}
    	    }
    	}
        }
        return dis[t] != inf;
    }
    
    int mcmf(int s, int t, int n)
    {
        int ans = 0, flow = inf, i;
        while (spfa(s, t, n)) {
    	for (i = p[t]; i != -1; i = p[e[i].v])
    	    if (e[i].f < flow)
    		flow = e[i].f;
    	for (i = p[t]; i != -1; i = p[e[i].v]) {
    	    e[i].f -= flow;
    	    e[i ^ 1].f += flow;
    	}
    	ans += dis[t] * flow;
    	flow_sum += flow;
        }
        return ans;
    }
    
    int main()
    {
    //freopen("input","r",stdin);
        while (scanf("%d%d%d", &N, &M, &K) == 3 && N && M && K) {
    	ans = 0;
    	for (int i = 1; i <= N; i++) {
    	    for (int j = 1; j <= K; j++) {
    		scanf("%d", &need[i][j]);
    	    }
    	}
    	for (int i = 1; i <= M; i++) {
    	    for (int j = 1; j <= K; j++) {
    		scanf("%d", &supply[i][j]);
    	    }
    	}
    	bool flag = true;
    	for (int k = 1; k <= K; k++) {	//第k种货物
    	    flow_sum = 0;
    	    tot = 0;
    	    memset(start, -1, sizeof(start));
    	    for (int i = 1; i <= N; i++) {
    		for (int j = 1; j <= M; j++) {
    		    scanf("%d", &cost);
    		    if (flag)
    			add(j, M + i, 10000000, cost);
    		}
    	    }
    	    for (int i = 1; i <= M; i++) {
    		if (flag)
    		    add(0, i, supply[i][k], 0);
    	    }
    	    for (int i = 1; i <= N; i++) {
    		if (flag)
    		    add(M + i, M + N + 1, need[i][k], 0);
    	    }
    	    if (flag) {
    		ans += mcmf(0, N + M + 1, N + M + 2);
    
    		good_sum = 0;
    		for (int t = 1; t <= N; t++)
    		    good_sum += need[t][k];
    
    		if (flow_sum < good_sum)	//所能达到的最大流小于需要的
    		    flag = false;
    	    }
    	}
    	if (flag)
    	    printf("%d\n", ans);
    	else
    	    printf("-1\n");
        }
    }
    

  • 相关阅读:
    sqlserver中判断表或临时表是否存在
    Delphi 简单方法搜索定位TreeView项
    hdu 2010 水仙花数
    hdu 1061 Rightmost Digit
    hdu 2041 超级楼梯
    hdu 2012 素数判定
    hdu 1425 sort
    hdu 1071 The area
    hdu 1005 Number Sequence
    hdu 1021 Fibonacci Again
  • 原文地址:https://www.cnblogs.com/Open_Source/p/1904871.html
Copyright © 2011-2022 走看看