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); } }
也算是一种模型了吧,虽说比起下面要见到的来说简单太多。。