zoukankan      html  css  js  c++  java
  • poj 2516 最小费用最大流

    原来这个代码超时
    #include<stdio.h>
    #include<queue>
    #include<string.h>
    using namespace std;
    #define N  200
    #define inf 0x3fffffff
    int cap[N][N];
    int  fee[N][N];
    int s,t,sum,pre[N];
    int spfa() {
    queue<int>q;
    int dis[N],visit[N],u,i;
    memset(pre,-1,sizeof(pre));
    memset(visit,0,sizeof(visit));
    q.push(s);
    visit[s]=1;
    for(i=s;i<=t;i++)
        dis[i]=inf;
        dis[s]=0;
    while(!q.empty()) {
        u=q.front();
        q.pop();
        visit[u]=0;
        for(i=s;i<=t;i++) {
            if(cap[u][i]&&dis[i]>dis[u]+fee[u][i]) {
                dis[i]=dis[u]+fee[u][i];
                pre[i]=u;
                if(!visit[i]) {
                    visit[i]=1;
                    q.push(i);
                }
            }
        }
    }
    //printf("%d
    ",dis[t]);
    if(dis[t]>=inf)return -1;
    return dis[t];
    }
    void min_cost(){
       int k,i,minn;
       while((k=spfa())!=-1) {
        minn=inf;
        for(i=t;i!=s;i=pre[i])
        if(minn>cap[pre[i]][i])
            minn=cap[pre[i]][i];
        sum=sum+minn*k;
        for(i=t;i!=s;i=pre[i]) {
            cap[pre[i]][i]-=minn;
            cap[i][pre[i]]+=minn;
        }
       }
       return ;
    }
    int main() {
       int n,m,k,i,j,need[N][N],ii,supply[N][N],ne[N],su[N],flag;
       while(scanf("%d%d%d",&n,&m,&k),n||m||k) {
        memset(su,0,sizeof(su));
        memset(ne,0,sizeof(ne));
        flag=0;s=0;t=n+m+1;sum=0;
        for(i=1;i<=n;i++)
        for(j=1;j<=k;j++) {
            scanf("%d",&need[i][j]);
           ne[j]+=need[i][j];
        }
        for(i=1;i<=m;i++)
        for(j=1;j<=k;j++) {
            scanf("%d",&supply[i][j]);
            su[j]+=supply[i][j];
        }
        flag=0;
        for(i=1;i<=k;i++)
        if(ne[i]>su[i]) {
            flag=1;
            break;
        }
        for(ii=1;ii<=k;ii++){
                memset(cap,0,sizeof(cap));
        for(i=1;i<=n;i++) 
        for(j=1;j<=m;j++) {
            scanf("%d",&fee[j][m+i]);
            fee[m+i][j]=-fee[j][m+i];
            cap[j][m+i]=inf;
        }
        if(flag)continue;
        for(i=1;i<=n;i++) {
            cap[m+i][t]=need[i][ii];
            fee[m+i][t]=fee[t][m+i]=0;
        }
        for(i=1;i<=m;i++) {
            cap[s][i]=supply[i][ii];
            fee[s][i]=fee[i][s]=0;
        }
        min_cost();
        }
        if(flag==0)
            printf("%d
    ",sum);
        else
            printf("-1
    ");
       }
    return 0;
    }
    改一点就对了,为什么?
    #include<stdio.h>
    #include<queue>
    #include<string.h>
    using namespace std;
    #define N  200
    #define inf 0x3fffffff
    int cap[N][N];
    int  fee[N][N];
    int s,t,sum,pre[N];
    int spfa() {
    queue<int>q;
    int dis[N],visit[N],u,i;
    memset(pre,-1,sizeof(pre));
    memset(visit,0,sizeof(visit));
    q.push(s);
    visit[s]=1;
    for(i=s;i<=t;i++)
        dis[i]=inf;
        dis[s]=0;
    while(!q.empty()) {
        u=q.front();
        q.pop();
        visit[u]=0;
        for(i=s;i<=t;i++) {
            if(cap[u][i]&&dis[i]>dis[u]+fee[u][i]) {
                dis[i]=dis[u]+fee[u][i];
                pre[i]=u;
                if(!visit[i]) {
                    visit[i]=1;
                    q.push(i);
                }
            }
        }
    }
    //printf("%d
    ",dis[t]);
    if(dis[t]>=inf)return -1;
    return dis[t];
    }
    void min_cost(){
       int k,i,minn;
       while((k=spfa())!=-1) {
        minn=inf;
        for(i=t;i!=s;i=pre[i])
        if(minn>cap[pre[i]][i])
            minn=cap[pre[i]][i];
        sum=sum+minn*k;
        for(i=t;i!=s;i=pre[i]) {
            cap[pre[i]][i]-=minn;
            cap[i][pre[i]]+=minn;
        }
       }
       return ;
    }
    int main() {
       int n,m,k,i,j,need[N][N],ii,supply[N][N],ne[N],su[N],flag;
       while(scanf("%d%d%d",&n,&m,&k),n||m||k) {
        memset(su,0,sizeof(su));
        memset(ne,0,sizeof(ne));
        flag=0;s=0;t=n+m+1;sum=0;
        for(i=1;i<=n;i++)
        for(j=1;j<=k;j++) {
            scanf("%d",&need[i][j]);
           ne[j]+=need[i][j];
        }
        for(i=1;i<=m;i++)
        for(j=1;j<=k;j++) {
            scanf("%d",&supply[i][j]);
            su[j]+=supply[i][j];
        }
        flag=0;
        for(i=1;i<=k;i++)
        if(ne[i]>su[i]) {
            flag=1;
            break;
        }
        for(ii=1;ii<=k;ii++){
                memset(cap,0,sizeof(cap));//
        memset(fee,0,sizeof(fee));//
        for(i=1;i<=n;i++) 
        for(j=1;j<=m;j++) {
            scanf("%d",&fee[j][m+i]);
            fee[m+i][j]=-fee[j][m+i];
            cap[j][m+i]=inf;
        }
        if(flag)continue;
        for(i=1;i<=n;i++) 
            cap[m+i][t]=need[i][ii];
        for(i=1;i<=m;i++) 
            cap[s][i]=supply[i][ii];
        min_cost();
        }
        if(flag==0)
            printf("%d
    ",sum);
        else
            printf("-1
    ");
       }
    return 0;
    }

  • 相关阅读:
    微信公众号教程(5)自动回复操作案例
    微信公众号教程(4)微信公众平台编辑模式介绍
    微信公众号教程(3)微信公众平台群发消息
    微信公众号教程(2)微信公众平台后台介绍
    微信公众号教程(1)微信公众账号注册、设置、登陆
    二级c程序设计题(2)
    二级c程序设计题(1)
    C++经典编程题#6:分配病房
    C++经典编程题#5:寻找下标
    python-----面向对象三大特性
  • 原文地址:https://www.cnblogs.com/thefirstfeeling/p/4410669.html
Copyright © 2011-2022 走看看