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