POJ 2516 Minimum Cost
问题:最小费用最大流
思路:针对对每一个物品建立网络流图求最小费用最大流,然后求和即可
PS:mincost忘了每次都初始化为0,导致一直WA!用尽了半天的时间去寻找,蓦然回首,原来mincost没有初始化!
View Code
#include <stdio.h>
#include <memory.h>
#define N 52
#define N2 104
#define M 5202
#define MAXVAL 0xfffffff
#define MOV(x) (x=(x+1)%N2)
int n,m,k,s,t;
int need[N][N],supply[N][N];
int nodevp[N2],nodeu[M],flow[M],cost[M],next[M],ind;
int getPartDataAndCheck()//首先得到need和supply的数据判断是否供大于求
{
int i,j;
scanf("%d %d %d",&n,&m,&k);
if(0==n) return 0;
for(i=1;i<=n;i++)
for(j=1;j<=k;j++)
scanf("%d",need[i]+j);
for(i=1;i<=m;i++)
for(j=1;j<=k;j++)
scanf("%d",supply[i]+j);
for(i=1;i<=k;i++)
{
need[0][i]=0;
for(j=1;j<=n;j++)
need[0][i]+=need[j][i];
supply[0][i]=0;
for(j=1;j<=m;j++)
supply[0][i]+=supply[j][i];
if(need[0][i]>supply[0][i]) return -1;
}
return 1;
}
void eatData(int lineNum)//“吃数据”
{
// char s[100];
// while(lineNum--) gets(s);
char ch;
while((ch=getchar())=='\n' || ch==' ');
while(lineNum--) while((ch=getchar())!='\n');
}
void addedge(int v,int u,int fw,int ct)
{
nodeu[ind]=u;
flow[ind]=fw;
cost[ind]=ct;
next[ind]=nodevp[v];
nodevp[v]=ind++;
}
void buildGraph(int goodsNum)//以编号为goodsNum的物品,进行建图
{
int i,j,val;
s=0; t=m+n+1;
memset(nodevp,-1,sizeof(nodevp)); ind=0;
for(i=1;i<=m;i++)
if(supply[i][goodsNum])//去除不需要建的边
addedge(s,i,supply[i][goodsNum],0) , addedge(i,s,0,0);
for(i=1;i<=n;i++)
if(need[i][goodsNum])//去除不需要建的边
addedge(i+m,t,need[i][goodsNum],0) , addedge(t,i+m,0,0);
for(i=1;i<=n;i++)
{
if(0==need[i][goodsNum]) eatData(1);//去除不需要建的边
else
{
for(j=1;j<=m;j++)
{
scanf("%d",&val);
if(supply[j][goodsNum])//去除不需要建的边
addedge(j,i+m,MAXVAL,val) , addedge(i+m,j,0,-val);
}
}
}
}
int queue[N2],font,rear;
int inqueue[N2],pre[N2],dist[N2];
int SPFA()
{
int i,v,u;
for(i=1;i<=t;i++) dist[i]=MAXVAL; dist[s]=0;
memset(inqueue,0,sizeof(inqueue));
memset(pre,-1,sizeof(pre));
font=rear=0; queue[MOV(rear)]=s; inqueue[s]=1;
while(font!=rear)
{
v=queue[MOV(font)]; inqueue[v]=0;
for(i=nodevp[v];~i;i=next[i])
{
u=nodeu[i];
if(flow[i] && dist[u]>dist[v]+cost[i])
{
dist[u]=dist[v]+cost[i]; pre[u]=i;
if(!inqueue[u]) queue[MOV(rear)]=u,inqueue[u]=1;
}
}
}
if(dist[t]!=MAXVAL) return 1;
else return 0;
}
int mincost_maxflow()
{
int i,minflow,mincost=0;
while(SPFA())
{
minflow=MAXVAL;
for(i=pre[t];~i;i=pre[nodeu[i^1]])
if(minflow>flow[i])
minflow=flow[i];
for(i=pre[t];~i;i=pre[nodeu[i^1]])
{
mincost+=cost[i]*minflow;
flow[i]-=minflow;
flow[i^1]+=minflow;
}
}
return mincost;
}
void solve()
{
int i,tmp,mincost; /* mincost=0; */
while(tmp=getPartDataAndCheck())
{
if(tmp==-1)
{
eatData(k*n);
printf("-1\n");
}
else
{
mincost=0;
for(i=1;i<=k;i++)//针对每一个物品建图,求最小费用最大流!
{
buildGraph(i);
mincost+=mincost_maxflow();
}
printf("%d\n",mincost);
}
}
}
int main()
{
// freopen("input.txt","r",stdin);
solve();
return 0;
}