Minimum Cost POJ

来源:互联网 发布:数据库常用sql语句 编辑:程序博客网 时间:2024/06/05 23:41
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 longconst 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");}elseprintf("%d\n",ans);}}

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