运输问题
Posted liguanlin1124
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了运输问题相关的知识,希望对你有一定的参考价值。
题目描述:
https://www.luogu.org/problemnew/show/P4015
题解:
建图跑最小费用流。
对于最大费用,我们可以重新建边,并把权值变成相反数。
也称 最大费用最大流。
代码:
#include<queue> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 105 #define ll long long inline int rd() { int f=1,c=0;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){c=10*c+ch-‘0‘;ch=getchar();} return f*c; } int m,n,S,T,hed1[2*N],cnt1=-1,hed2[2*N],cnt2=-1; const ll inf = 0x3f3f3f3f3f3f3f3fll; struct EG { int to,nxt; ll vl,w; }e1[N*N*2],e2[N*N*2]; void ae(int f,int t,ll v,ll w) { e1[++cnt1].to = t; e1[cnt1].vl = v; e1[cnt1].w = w; e1[cnt1].nxt = hed1[f]; hed1[f] = cnt1; e2[++cnt2].to = t; e2[cnt2].vl = v; e2[cnt2].w = -w; e2[cnt2].nxt = hed2[f]; hed2[f] = cnt2; } int vis[N*2],pre[N*2],fa[N*2]; ll dis[N*2],f[N*2]; bool spfa1() { queue<int>q; q.push(S); memset(dis,0x3f,sizeof(dis)); memset(f,0,sizeof(f)); dis[S]=0;f[S]=inf; while(!q.empty()) { int u = q.front(); q.pop(); vis[u]=0; for(int j=hed1[u];~j;j=e1[j].nxt) { int to = e1[j].to; if(e1[j].vl&&dis[to]>dis[u]+e1[j].w) { dis[to]=dis[u]+e1[j].w; f[to]=min(f[u],e1[j].vl); pre[to]=j;fa[to]=u; if(!vis[to]) { vis[to]=1; q.push(to); } } } } return dis[T]!=inf; } ll mcmf1() { ll ret = 0; while(spfa1()) { ret+=dis[T]*f[T]; int tmp = T; while(tmp!=S) { e1[pre[tmp]].vl-=f[T]; e1[pre[tmp]^1].vl+=f[T]; tmp=fa[tmp]; } } return ret; } bool spfa2() { queue<int>q; q.push(S); memset(dis,0x3f,sizeof(dis)); memset(f,0,sizeof(f)); dis[S]=0;f[S]=inf; while(!q.empty()) { int u = q.front(); q.pop(); vis[u]=0; for(int j=hed2[u];~j;j=e2[j].nxt) { int to = e2[j].to; if(e2[j].vl&&dis[to]>dis[u]+e2[j].w) { dis[to]=dis[u]+e2[j].w; f[to]=min(f[u],e2[j].vl); pre[to]=j;fa[to]=u; if(!vis[to]) { vis[to]=1; q.push(to); } } } } return dis[T]!=inf; } ll mcmf2() { ll ret = 0; while(spfa2()) { ret+=dis[T]*f[T]; int tmp = T; while(tmp!=S) { e2[pre[tmp]].vl-=f[T]; e2[pre[tmp]^1].vl+=f[T]; tmp=fa[tmp]; } } return ret; } int main() { memset(hed1,-1,sizeof(hed1)); memset(hed2,-1,sizeof(hed2)); m=rd(),n=rd(); S=0,T=m+n+1; for(int a,i=1;i<=m;i++) { a=rd(); ae(S,i,1ll*a,0); ae(i,S,0,0); } for(int b,i=1;i<=n;i++) { b=rd(); ae(i+m,T,1ll*b,0); ae(T,i+m,0,0); } for(int i=1;i<=m;i++) { for(int c,j=1;j<=n;j++) { c=rd(); ae(i,j+m,inf,c); ae(j+m,i,0,-c); } } ll ans1 = mcmf1(); ll ans2 = -mcmf2(); printf("%lld %lld ",ans1,ans2); return 0; }
以上是关于运输问题的主要内容,如果未能解决你的问题,请参考以下文章