Minimum Cost POJ - 2516 费用流

k种商品的源汇分配

朴素的算k次最大流,没人知道如果数据大怎么办吗。。。

//#include<bits/stdc++.h>
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<string.h>
#include<iostream>
#include<math.h>

using namespace std;
#define ll long long
const int maxn=5e5+5;
const int maxm=5e5+7;
const int inf=0x3f3f3f3f;
struct EDGE{
	int to,next,cap,flow,cost;
}edge[maxn];
int head[maxn],tot;
int pre[maxn],dis[maxn];
int vis[maxn];

int source,sink;
int num_nodes;

void init(){
	tot=0;
	memset(head,-1,sizeof head);
}
void addedge(int u,int v,int cap,int cost){
	edge[tot]=(EDGE){v,head[u],cap,0,cost};
	head[u]=tot++;
	edge[tot]=(EDGE){u,head[v],0,0,-cost};
	head[v]=tot++;
}
int spfa(int s,int t){
	queue<int>Q;
	for(int i=0;i<num_nodes;i++){
		dis[i]=inf;
		vis[i]=0;
		pre[i]=-1;
	}
	dis[s]=0;
	vis[s]=1;
	Q.push(s);
	while(!Q.empty()){
		//cout<<"wwww"<<endl;
		int u=Q.front();
		Q.pop();
		vis[u]=0;
		for(int i=head[u];~i;i=edge[i].next){
			int v=edge[i].to;
			if(edge[i].cap>edge[i].flow && dis[v]>dis[u]+edge[i].cost){
				dis[v]=dis[u]+edge[i].cost;
				pre[v]=i;
				if(!vis[v]){
					vis[v]=1;
					Q.push(v);
				}
			}
		}
	}
	if(pre[t]==-1)return 0;
	return 1;
}
int mcmf(int &cost){
	int s=source,t=sink;
	int flow=0;
	cost=0;
	while(spfa(s,t)){

		int minflow=inf;
		for(int i=pre[t];~i;i=pre[edge[i^1].to]){
			minflow=min(minflow,edge[i].cap-edge[i].flow);
		}
		for(int i=pre[t];~i;i=pre[edge[i^1].to]){
			edge[i].flow+=minflow;
			edge[i^1].flow-=minflow;
			cost+=edge[i].cost*minflow;
		}
		flow+=minflow;
	}
	return flow;
}

int sup[55][55];//第i个供应商有几个j号商品
int ned[55][55];//第i个需求者要几个j号商品
int spt[55][55];//第j个供应给第i个的花费

int main(){
	int n,m,k;//50, m种源,n个汇,k种物品
	while(~scanf("%d%d%d",&n,&m,&k)&&n){

		num_nodes=n+m+2;
		
		for(int i=1;i<=n;i++){
			for(int j=1;j<=k;j++){
				scanf("%d",&ned[i][j]);
			}
		}
		for(int i=1;i<=m;i++){
			for(int j=1;j<=k;j++){
				scanf("%d",&sup[i][j]);
			}
		}
		int fail=0;	
		for(int i=1;i<=k;i++){
			int cmp1=0,cmp2=0;
			for(int j=1;j<=m;j++)cmp1+=sup[j][i];
			for(int j=1;j<=n;j++)cmp2+=ned[j][i];
			if(cmp1<cmp2)fail=1;			
		}
			
		source=0;
		sink=n+m+1;

		int ans=0;
		for(int i=1;i<=k;i++){//k个花费矩阵
			init();
			for(int j=1;j<=n;j++){
				for(int q=1;q<=m;q++){
					scanf("%d",&spt[j][q]);
					addedge(q,j+m,inf,spt[j][q]);
				}
			}
			if(fail)continue;
			for(int j=1;j<=m;j++){
				addedge(0,j,sup[j][i],0);
			}
			for(int j=1;j<=n;j++){
				addedge(j+m,sink,ned[j][i],0);
			}
			int costt;mcmf(costt);
			ans+=costt;

		}
		if(fail){
			printf("-1\n");
		}else
		printf("%d\n",ans);
	}	
}

也算是一种模型了吧,虽说比起下面要见到的来说简单太多。。

posted @ 2017-07-04 22:19  Drenight  阅读(88)  评论(0编辑  收藏  举报