其他分享
首页 > 其他分享> > 洛谷P2517 HAOI2010 订货 (费用流)

洛谷P2517 HAOI2010 订货 (费用流)

作者:互联网

标准的费用流问题,关键在于巧妙地建模

一共有n个月份,源点设为0,汇点设为n+1

1.源点向所有月份连边,容量为正无穷,费用为该月进货的费用

2.每个月向下一个月连边,容量为仓库容量,费用为存货费用

3.每个月向汇点连边,容量为该月卖货的数量,费用为0(卖货不会产生费用)

用最小费用最大流求解即可


————————————————
版权声明:本文为CSDN博主「ynhnxn」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/C_sat/article/details/123443008

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int INF=20000000,tot=1,n,ans=0;
 4 int nex[1000],adj[1000],to[1000],cap[1000],cost[1000];
 5 int d[60],que[2000000];
 6 bool vis[1000];
 7  
 8 void add(int u,int v,int w,int c){
 9     nex[++tot]=adj[u];
10     adj[u]=tot;
11     to[tot]=v;
12     cap[tot]=w;
13     cost[tot]=c;
14 }
15  
16 int SPFA(){//标准SPFA 
17     int q1=0,q2=1;
18     que[1]=0;
19     for(int i=1;i<=n+1;i++) d[i]=INF,vis[i]=0;
20     while(q1<q2){
21         int x=que[++q1];
22         vis[x]=0;
23         for(int k=adj[x];k;k=nex[k]){
24             int y=to[k];
25             if(d[x]+cost[k]<d[y]&&cap[k]){
26                 d[y]=d[x]+cost[k];
27                 if(!vis[y]){
28                     vis[y]=1;que[++q2]=y;
29                 }
30             }
31         }
32     }
33     if(d[n+1]==INF) return 0;
34     for(int i=0;i<=n+1;i++){
35         if(d[i]!=INF) vis[i]=0;
36     }
37     return 1;
38 }
39  
40 int dinic(int u,int fw){//标准dinic 
41     if(u==n+1){
42         ans+=fw*d[n+1];
43         return fw;
44     }
45     vis[u]=1;
46     int rest=fw;
47     for(int i=adj[u];i&&rest;i=nex[i]){
48         int v=to[i];
49         if(!vis[v]&&d[v]==d[u]+cost[i]&&cap[i]>0){
50             int k=dinic(v,min(rest,cap[i]));
51             if(k){
52                 rest-=k;
53                 cap[i]-=k;
54                 cap[i^1]+=k;
55             }
56         }
57     }
58     return fw-rest;
59 }
60  
61 int main(){//源点为0,汇点为n+1 
62     int x,m,s;
63     scanf("%d%d%d",&n,&m,&s);//月份数,存贮费,仓库容量 
64     for(int i=1;i<=n;i++){
65         scanf("%d",&x);//需求量 
66         add(i,n+1,x,0);
67         add(n+1,i,0,0);//每个月向汇点连边,容量为x,费用为0 
68         if(i!=n) add(i,i+1,s,m),add(i+1,i,0,-m);//向下一个月连边,容量就是仓库容量s,费用是m 
69     }
70     for(int i=1;i<=n;i++){
71         scanf("%d",&x);//订货单价 
72         add(0,i,INF,x);
73         add(i,0,0,-x);//源点向每个月连边,容量为正无穷,费用为订货价格 
74     }
75     while(SPFA()) dinic(0,INF);//最小费用最大流 
76     cout<<ans;
77 }

 

标签:费用,源点,洛谷,int,P2517,cap,tot,HAOI2010,1000
来源: https://www.cnblogs.com/yhxnoerror/p/16099190.html