• POJ 2516 Minimum Cost [最小费用最大流]


    题意略;

    思路:

    这题比较坑的地方是把每种货物单独建图分开算就ok了。

    #include<stdio.h>
    #include<queue>
    #define MAXN 500
    #define MAXM 10002*4
    #define INF  10000000
    using namespace std;
    //起点编号必须最小,终点编号必须最大
    bool vis[MAXN];                    //spfa中记录是否在队列里边
    char pho[105][105];
    int max_flow;
    struct point{
        int x,y;
    }man[105],house[105];
    struct edge{
        edge *next,*op;                //op是指向反向边
        int t,c,v;                     //t下一个点编号,c容量,v权值
    }ES[MAXM],*V[MAXN];                //ES边静态邻接表,V点的编号
    struct st{
        int num[55];
    };
    st from[55],to[55];
    int N,M,S,T,EC=-1;                 //S源点最小,T汇点最大,EC当前边数
    int demond[MAXN],sp[MAXN],prev[MAXN]; //spSPFA中记录距离,prev记录上一个点路径
    edge *path[MAXN];                  //与prev同步记录,记录到上一条边
    void addedge(int a,int b,int v,int c=INF){
        //printf("*  %d %d %d %d
    ",a,b,v,c);
        edge e1={V[a],0,b,c,v},e2={V[b],0,a,0,-v};
        ES[++EC]=e1;V[a]=&ES[EC];
        ES[++EC]=e2;V[b]=&ES[EC];
        V[a]->op=V[b];V[b]->op=V[a];
    }
    bool SPFA(){
        int u,v;
        for(u=S;u<=T;u++){
            sp[u]=INF;
        }
        queue<int>q;
        prev[S]=-1;
        q.push(S);
        sp[S]=0;
        vis[S]=1;
        while(!q.empty()){
            u=q.front();
            vis[u]=0;
            q.pop();
            for(edge *k=V[u];k;k=k->next){
                v=k->t;
                if(k->c>0&&sp[u]+k->v<sp[v]){
                    sp[v]=sp[u]+k->v;
                    prev[v]=u;
                    path[v]=k;
                    if(vis[v]==0){
                        vis[v]=1;
                        q.push(v);
                    }
                }
            }
        }
        return sp[T]!=INF;
    }
    int argument(){
        int i,cost=INF,flow=0;
        edge *e;
        for(i=T;prev[i]!=-1;i=prev[i]){
            e=path[i];
            if(e->c<cost)cost=e->c;
        }
        max_flow+=cost;
        for(int i=T;prev[i]!=-1;i=prev[i]){
            e=path[i];
            e->c-=cost;e->op->c+=cost;
            flow+=e->v*cost;
        }
        return flow;
    }
    int maxcostflow(){
        int Flow=0;
        while(SPFA()){
            Flow+=argument();
        }
        return Flow;
    }
    bool init(){
        int n,m,k;
        bool ok=1;
        long long ans=0;
        scanf("%d%d%d",&n,&m,&k);
        if(n==0&&m==0&&k==0)return 0;
        for(int i=0;i<n;i++){
            for(int j=0;j<k;j++){
                scanf("%d",&to[i].num[j]);
            }
        }
        for(int i=0;i<m;i++){
            for(int j=0;j<k;j++){
                scanf("%d",&from[i].num[j]);
            }
        }
        for(int i=0;i<k;i++){
            EC=-1;
            max_flow=0;
            for(int j=0;j<=MAXN;j++){
                V[j]=NULL;
            }
            for(int j=0;j<n;j++){
                for(int w=0;w<m;w++){
                    int tmp;
                    scanf("%d",&tmp);
                    addedge(w+1,m+j+1,tmp);
                }
            }
            for(int j=0;j<m;j++){
                addedge(0,j+1,0,from[j].num[i]);
            }
            int sum=0;
            for(int j=0;j<n;j++){
                addedge(j+1+m,m+n+1,0,to[j].num[i]);
                sum+=to[j].num[i];
            }
            S=0;T=n+m+1;
            ans+=maxcostflow();
            if(max_flow!=sum)ok=0;
        }
        if(!ok)ans=-1;
        printf("%I64d
    ",ans);
        return 1;
    }
    int main(){
        while(init());
        return 0;
    }
  • 相关阅读:
    java8 快速实现List转map 、分组、过滤等操作
    Centos7系统备份与恢复
    BDI3000仿真器命令
    MIPS32地址映射和TLB
    三层交换机之报文转发流程
    三层交换机之搜索引擎
    三层交换机之端口丢包问题分析
    嵌入式Linux之虚拟内存管理
    Windows网络命令大全
    三层交换机之端口镜像(Mirror)
  • 原文地址:https://www.cnblogs.com/tun117/p/5413817.html
Copyright © 2020-2023  润新知