hdu 4780 Candy Factory(费用流)
来源:互联网 发布:java 7 64位 解压包 编辑:程序博客网 时间:2024/05/16 08:43
题意:给出m个机器,现在要生产n个糖果,每个糖果可以在任意一个机器上生产,每个糖果的生产时间是一个区间[s,t],必须在[s,t)时间内开始生产,否则就无法生产了,生产的费用为(p-s)*k,p是开始生产的时间。对于一个机器j来说,从最开始没生产的状态转化为生产第i个糖果的状态需要花费C[i][j]的时间并花费D[i][j],对于一个在生产第i个糖果的机器来说,将其转化为生产第j个糖果需要花费E[i][j]的时间并花费F[i][j],现在要生产这n个糖果并让所有花费最小。
思路:一看就是个网络流的问题,不过建图还是有些麻烦的,首先将n个糖果拆成两个点,如果左边第i个糖果生产完,可以生产右边的j,那么连边,流量为1,费用为转换的费用+生产费用,S向左边的点连边,流量为1,费用为0,右边的点向T连边,流量为1,费用为0。添加点u,从S向u连边,流量为m,费用为0,再从u向m个点连边,流量为1,费用为0,接下来m个点代表最开始这个机器生产哪个糖果,如果可以最开始生产某个糖果,向右边的对应点连边,流量为1,费用为转换费用+生产费用。这样就能保证最后的费用流就是答案。
代码:
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<map>#include<queue>#include<stack>#include<cmath>#include<vector>#include<bitset>#define inf 0x3f3f3f3f#define Inf 0x3FFFFFFFFFFFFFFFLL#define eps 1e-6#define pi acos(-1.0)using namespace std;typedef long long ll;const int maxn=300+10;const int maxm=100000+10;struct Edge{ int to,cap,cost,next; Edge(int to=0,int cap=0,int cost=0,int next=0):to(to),cap(cap),cost(cost),next(next){}}edges[maxm<<1];int head[maxn],d[maxn],a[maxn],p[maxn],nEdge,S,T;bool inq[maxn];int st[maxn],tt[maxn],C[maxn][maxn],D[maxn][maxn],E[maxn][maxn],F[maxn][maxn];void AddEdges(int from,int to,int cap,int cost){ edges[++nEdge]=Edge(to,cap,cost,head[from]); head[from]=nEdge; edges[++nEdge]=Edge(from,0,-cost,head[to]); head[to]=nEdge;}int spfa(int &flow,int &cost){ memset(inq,0,sizeof(inq)); memset(d,0x3f,sizeof(d)); queue<int>q; q.push(S); d[S]=0;a[0]=inf; while(!q.empty()) { int u=q.front();q.pop(); inq[u]=false; for(int k=head[u];k!=-1;k=edges[k].next) { Edge &e=edges[k]; if(d[e.to]>d[u]+e.cost&&e.cap) { d[e.to]=d[u]+e.cost; a[e.to]=min(a[u],e.cap); p[e.to]=k; if(!inq[e.to]) {inq[e.to]=true;q.push(e.to);} } } } if(d[T]==inf) return false; flow+=a[T]; cost+=a[T]*d[T]; int u=T; while(u!=S) { edges[p[u]].cap-=a[T]; edges[p[u]^1].cap+=a[T]; u=edges[p[u]^1].to; } return true;}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int n,m,K; while(~scanf("%d%d%d",&n,&m,&K)) { if(n==0&&m==0&&K==0) break; memset(head,0xff,sizeof(head)); nEdge=-1; for(int i=1;i<=n;++i) scanf("%d%d",&st[i],&tt[i]); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) scanf("%d",&C[i][j]); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) scanf("%d",&D[i][j]); for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) scanf("%d",&E[i][j]); for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) scanf("%d",&F[i][j]); S=0,T=n*2+m+2; for(int i=1;i<=n;++i) { AddEdges(S,i,1,0); AddEdges(i+n,T,1,0); for(int j=1;j<=n;++j) { if(i!=j&&tt[i]+E[i][j]<tt[j]) { int c=max(tt[i]+E[i][j],st[j])-st[j]; c*=K; AddEdges(i,n+j,1,c+F[i][j]); } } } AddEdges(S,n*2+m+1,m,0); for(int i=1;i<=m;++i) { AddEdges(n*2+m+1,n*2+i,1,0); for(int j=1;j<=n;++j) { if(C[j][i]<tt[j]) { int c=max(C[j][i],st[j])-st[j]; c*=K; AddEdges(n*2+i,j+n,1,c+D[j][i]); } } } int flow=0,cost=0; while(spfa(flow,cost)); if(flow!=n) printf("-1\n"); else printf("%d\n",cost); } return 0;}
0 0
- hdu-4780-Candy Factory--费用流
- hdu 4780 Candy Factory(费用流)
- HDU 4780 Candy Factory 费用流
- hdu 4780 Candy Factory(最小费用流--按流建图)
- hdu 4780 Candy Factory(最小费用流)
- hdu 4780 Candy Factory
- HDU 4780 Candy Factory
- HDU 4780 Candy Factory
- HDU 4780 Candy Factory(网络流)
- hdu-4322-Candy-费用流
- hdu 4322 Candy 费用流
- hdu 4322 Candy 【多校3】【费用流】
- hdu 4322 Candy 最大费用最大流
- HDU 4322 Candy 最大费用流
- hdu4322 Candy 费用流
- hdu4322 candy 费用流
- HDU 4322 Candy (最大费用最大流)经典
- HDU 4322 Candy 最大费用流+巧妙建图
- 【剑指offer】面试题9:斐波那契数列
- 设计模式——观察者模式
- Java学习笔记(四)
- linux内核posix文件锁实现
- 父母不同意结婚肯定有他们的理由,我现在也总算是明白了,一切也是他们看透了!
- hdu 4780 Candy Factory(费用流)
- 【Linux学习】Linux的文件权限(一)
- BZOJ2440(完全平方数)二分+莫比乌斯容斥
- cygwin 字符显示
- 裸机malloc实现
- PostGIS整合Hibernate4.0+Spring(Maven,Kepler)
- 弹出不可移动遮罩层
- 夏天小女孩子光着屁股很雅观吗?
- C99的指定初始化转化为C89?用(a|e)?bnf实现吧,写个玩玩