首页 > 代码库 > hdu 2516 最小费用最大流

hdu 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\n",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\n",sum);
    else
        printf("-1\n");
   }
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\n",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\n",sum);
    else
        printf("-1\n");
   }
return 0;
}