NYOJ1367 物流配送

题目描述:

物流配送是物流活动中一种非单一的业务形式,它与物品流动、资金流动紧密结合。备货是配送的准备工作或基础工作,备货工作包括筹集货源、订货或购货、集货、进货及有关的质量检查、结算、交接等。配送的优势之一,就是可以集中用户的需求进行一定规模的备货。备货是决定配送成败的初期工作,如果备货成本太高,会大大降低配送的效益。配送中的储存有储备及暂存两种形态。配送储备是按一定时期的配送经营要求,形成的对配送的资源保证。这种类型的储备数量较大,储备结构也较完善,视货源及到货情况,可以有计划地确定周转储备及保险储备结构及数量。

Dr. Kong 所在的研究团队准备为Hai-E集团开发一个物流配送管理系统。已知Hai-E集团已经在全国各地建立了n个货物仓库基地,任意两个基地的货物可以相互调配。现在需要根据用户订货要求,来重新调配每个基地的货物数量。为了节流开源,希望对整个物流配送体系实行统一的货物管理和调度,能够提供一个全面完善的物流仓储配送解决方案,以减少物流配送过程中成本、人力、时间。

 

输入描述:

第一行:   n             (1 ≤ n ≤ 1000)

第2行:   a1  a2 …… an    表示n个基地当前的物品数量             (0≤ ai ≤ 106 )

第3行:   b1  b2 …… bn   表示调配后,每个基地i应不少于bi个物品  (0≤ bi ≤ 106)

接下来n-1行,每行三个整数: i  j  k 表示从第i基地调配一个物品到第j基地需要花费为k,或 从第j基地调配一个物品到第i基地需要花费为k。(0≤ k ≤ 10^6)

输出描述:

输出配送后的最小费用。

已知: a1+a2+…+an >=b1+b2+…+bn

样例输入:

6
0 1 2 2 0 0
0 0 1 1 1 1
1 2 2    
1 3 5
1 4 1
2 5 5
2 6 1

样例输出:

9

提示:

 

来源:

 
思路:裸的最小费用最大流。 a_i 连 S, b_i连T, 流量为权值,费用为0。 其他边流量为inf,费用w_i 。测试模板
 
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 const int maxn=10000;
  5 const int maxm=100000;
  6 const int inf=0x3f3f3f3f;
  7 struct Edge{
  8     ll to,next,cap,flow,cost;
  9 }edge[maxm];
 10 
 11 int head[maxn],tol;
 12 int pre[maxn],dis[maxn];
 13 bool vis[maxn];
 14 int N;
 15 void init(int n) {
 16     N=n;
 17     tol=0;
 18     memset(head,-1,sizeof(head));
 19 }
 20 
 21 void addedge(int u,int v,ll cap,ll cost) {
 22     edge[tol].to=v;
 23     edge[tol].cap=cap;
 24     edge[tol].cost=cost;
 25     edge[tol].flow=0;
 26     edge[tol].next=head[u];
 27     head[u]=tol++;
 28     edge[tol].to=u;
 29     edge[tol].cap=0;
 30     edge[tol].cost=-cost;
 31     edge[tol].flow=0;
 32     edge[tol].next=head[v];
 33     head[v]=tol++;
 34 }
 35 
 36 bool spfa(int s,int t) {
 37     queue<int> q;
 38     for(int i=0;i<N;i++) {
 39         dis[i]=inf;
 40         vis[i]=false;
 41         pre[i]=-1;
 42     }
 43     dis[s]=0;
 44     vis[s]=true;
 45     q.push(s);
 46     while(!q.empty()) {
 47         int u=q.front();
 48         q.pop();
 49         vis[u]=false;
 50         for(int i=head[u];i!=-1;i=edge[i].next) {
 51             int v=edge[i].to;
 52             if(edge[i].cap>edge[i].flow&&dis[v]>dis[u]+edge[i].cost) {
 53                 dis[v]=dis[u]+edge[i].cost;
 54                 pre[v]=i;
 55                 if(!vis[v]) {
 56                     vis[v]=true;
 57                     q.push(v);
 58                 }
 59             }
 60         }
 61     }
 62     if(pre[t]==-1) return false;
 63     return true;
 64 }
 65 
 66 int minCostMaxflow(int s,int t,ll &cost) {
 67     int flow=0;
 68     cost=0;
 69     while(spfa(s,t)) {
 70         int Min=inf;
 71         for(int i=pre[t];i!=-1;i=pre[edge[i^1].to]) {
 72             if(Min>edge[i].cap-edge[i].flow)
 73                 Min=edge[i].cap-edge[i].flow;
 74         }
 75         for(int i=pre[t];i!=-1;i=pre[edge[i^1].to]) {
 76             edge[i].flow+=Min;
 77             edge[i^1].flow-=Min;
 78             cost+=edge[i].cost*Min;
 79         }
 80         flow+=Min;
 81     }
 82     return flow;
 83 }
 84 
 85 int n;
 86 int main() {
 87     while(~scanf("%d",&n)) {
 88         init(n+2);
 89         int x;
 90         for(int i=1;i<=n;i++) {
 91             scanf("%d",&x);
 92             addedge(0,i,x,0);
 93             addedge(i,0,0,0);
 94         }
 95         for(int i=1;i<=n;i++) {
 96             scanf("%d",&x);
 97             addedge(i,n+1,x,0);
 98             addedge(n+1,i,0,0);
 99         }
100         for(int i=1;i<=n-1;i++) {
101             int u,v,cost;
102             scanf("%d%d%d",&u,&v,&cost);
103             addedge(u,v,inf,cost);
104             addedge(v,u,inf,cost);
105         }
106         ll cost=0;
107         minCostMaxflow(0,n+1,cost);
108         printf("%lld\n",cost);
109     }
110 }

 

 
posted @ 2019-05-05 23:40  Frontierone  阅读(258)  评论(0编辑  收藏  举报