CCF 201412-5 货物调度
问题描述
某公司要处理一个周期性的物流问题。
有n个城市,第i个城市在每周的第j(1≤j≤7) 天会生产aij吨某种货物,同时需要消耗bij吨该种货物。已知每周的产量等于消耗量(即aij之和等于bij之和)。
城市之间有m条道路,第k条道路连接了城市sk和tk。一条道路上运输1吨货物有一个固定的成本ck。道路都可以双向使用。每天运输的货物量没有限制。城市之间的距离并不远,货物可以从任意一个城市运输到任意另一个城市并且在当天到达。
货物如果在当天没有被消耗掉,就需要存放在仓库里过夜。第i个城市的仓库容量为vi,存放1 吨货物过一夜所需的成本是wi。
请你计算该公司如果每周循环性地按照一个固定的流程调度货物的话,该公司在最优方案下每周需要为货物的运输和存储消耗多少成本。
有n个城市,第i个城市在每周的第j(1≤j≤7) 天会生产aij吨某种货物,同时需要消耗bij吨该种货物。已知每周的产量等于消耗量(即aij之和等于bij之和)。
城市之间有m条道路,第k条道路连接了城市sk和tk。一条道路上运输1吨货物有一个固定的成本ck。道路都可以双向使用。每天运输的货物量没有限制。城市之间的距离并不远,货物可以从任意一个城市运输到任意另一个城市并且在当天到达。
货物如果在当天没有被消耗掉,就需要存放在仓库里过夜。第i个城市的仓库容量为vi,存放1 吨货物过一夜所需的成本是wi。
请你计算该公司如果每周循环性地按照一个固定的流程调度货物的话,该公司在最优方案下每周需要为货物的运输和存储消耗多少成本。
输入格式
输入的第一行有两个正整数n和m,即城市的个数和道路的条数。
接下来有n行,每行包含16个整数,用以描述第i个城市的相关数据。其中第i行包含的数为ai1, ai2, ai3, ai4, ai5, ai6, ai7, bi1, bi2, bi3, bi4, bi5, bi6, bi7, vi, wi。
接下来有m行,每行包含3个整数,用以描述一条道路的相关数据。其中第k行包含的数为sk, tk和ck。
输入数据中城市的编号均为1到n之间。输入数据的每行的行首行尾均保证没有空格,两个数之间恰好被一个空格隔开。
接下来有n行,每行包含16个整数,用以描述第i个城市的相关数据。其中第i行包含的数为ai1, ai2, ai3, ai4, ai5, ai6, ai7, bi1, bi2, bi3, bi4, bi5, bi6, bi7, vi, wi。
接下来有m行,每行包含3个整数,用以描述一条道路的相关数据。其中第k行包含的数为sk, tk和ck。
输入数据中城市的编号均为1到n之间。输入数据的每行的行首行尾均保证没有空格,两个数之间恰好被一个空格隔开。
输出格式
你只需要输出一个数,即最优方案下每周的支出。
样例输入
3 3
0 0 0 0 5 0 0 0 0 0 0 0 0 0 2 4
0 0 0 0 0 0 0 2 0 0 0 0 0 0 2 1
0 0 0 0 0 0 0 0 0 3 0 0 0 0 2 5
1 2 1
1 3 5
2 3 1
0 0 0 0 5 0 0 0 0 0 0 0 0 0 2 4
0 0 0 0 0 0 0 2 0 0 0 0 0 0 2 1
0 0 0 0 0 0 0 0 0 3 0 0 0 0 2 5
1 2 1
1 3 5
2 3 1
样例输出
67
样例说明
城市1 每周五生产5 吨货物,把其中2 吨运到存储费用低廉的城市2 存储,把1 吨运到城市3 存储,剩下的2 吨留在城市1。
在次周一的时候城市2 会消耗掉存放在那里的2 吨货物。为了节约存储成本,将囤放在城市1 的货物运到城市2 存放。周三再将所有货物运到城市3 以满足该城市的需求。
在此方案下,每周的运输成本为8,每周的存储成本为59,因此每周的总支出为67。
在次周一的时候城市2 会消耗掉存放在那里的2 吨货物。为了节约存储成本,将囤放在城市1 的货物运到城市2 存放。周三再将所有货物运到城市3 以满足该城市的需求。
在此方案下,每周的运输成本为8,每周的存储成本为59,因此每周的总支出为67。
评测用例规模与约定
对于100%的数据,1≤n≤100,1≤m≤500,0≤aij,bij,vi≤100,1≤wi,ck≤100。
/* map: 1、S --(aij / 0)-> point ij ,(i<n,1<=j<=7); point ij--(bij / 0)->T 2、point ij --(vi / wi)-> point i(j+1) ,(i<n,1<=j<=6); point i7 --(vi / wi)-> point i1 3、point xj <--(inf / edge_wi)-> point yj (every (x,y)mentioned,1<=j<=7); */ #include<stdio.h> #include<string.h> #include<iostream> using namespace std; const int N=1005; const int inf=2e9; struct edge{int v,next,cap,cost;}e[N*400];int tot=1,head[N]; int n,m,ans,S,T,dis[N],pre[N],q[N*80];bool vis[N]; void add(int x,int y,int z,int cost=0){ e[++tot].v=y;e[tot].cap=z;e[tot].cost=cost;e[tot].next=head[x];head[x]=tot; e[++tot].v=x;e[tot].cap=0;e[tot].cost=-cost;e[tot].next=head[y];head[y]=tot; } bool spfa(){ memset(vis,0,sizeof vis); memset(dis,0x3f,sizeof dis); unsigned short h=0,t=1;q[t]=S;dis[S]=0;vis[S]=1; while(h!=t){ int x=q[++h];vis[x]=0; for(int i=head[x];i;i=e[i].next){ if(e[i].cap&&dis[e[i].v]>dis[x]+e[i].cost){ dis[e[i].v]=dis[x]+e[i].cost; pre[e[i].v]=i; if(!vis[e[i].v]){ vis[e[i].v]=1; q[++t]=e[i].v; } } } } return dis[T]<0x3f3f3f3f; } int augment(){ int flow=0x3f3f3f3f; for(int i=T;i!=S;i=e[pre[i]^1].v) flow=min(flow,e[pre[i]].cap); for(int i=T;i!=S;i=e[pre[i]^1].v){ e[pre[i]].cap-=flow; e[pre[i]^1].cap+=flow; } return dis[T]*flow; } int main(){ scanf("%d%d",&n,&m); S=0,T=n*7+1; for(int i=0,x,v,w;i<n;i++){ for(int j=1;j<=7;j++) scanf("%d",&x),add(S,i*7+j,x,0); for(int j=1;j<=7;j++) scanf("%d",&x),add(i*7+j,T,x,0); scanf("%d%d",&v,&w); for(int j=1;j<=6;j++) add(i*7+j,i*7+j+1,v,w); add(i*7+7,i*7+1,v,w); } for(int i=0,x,y,z;i<m;i++){ scanf("%d%d%d",&x,&y,&z); for(int i=1;i<=7;i++){ add((x-1)*7+i,(y-1)*7+i,inf,z); add((y-1)*7+i,(x-1)*7+i,inf,z); } } while(spfa()) ans+=augment(); printf("%d\n",ans); return 0; }