BZOJ 最小费用流最大流 1070: [SCOI2007]修车
2014-08-28 21:57
183 查看
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1070
建图方法:将一个工人拆成n个点,用以区分一个人修的每一次车都是不一样的。可以想到,一个工人假设安排他修x架车,那么第一輛车的等待时间就是修车时间,第二輛的等待时间是第一輛的时间加第二輛的时间....以此类推。那么对一个工人来讲,总的等待时间是: t1*x+t2*(x-1)+t3*(x-2)....+tx,所以我们对于每个工人拆出来的n个点,都连到另外n个点(表示的是车),费用就是对应的时间*k(拆出来的第一个点k就是1,第二个k就是2.....)
代码:
建图方法:将一个工人拆成n个点,用以区分一个人修的每一次车都是不一样的。可以想到,一个工人假设安排他修x架车,那么第一輛车的等待时间就是修车时间,第二輛的等待时间是第一輛的时间加第二輛的时间....以此类推。那么对一个工人来讲,总的等待时间是: t1*x+t2*(x-1)+t3*(x-2)....+tx,所以我们对于每个工人拆出来的n个点,都连到另外n个点(表示的是车),费用就是对应的时间*k(拆出来的第一个点k就是1,第二个k就是2.....)
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <string.h> #include <queue> #include <vector> #include <algorithm> #include <cassert> #include <set> #include <map> #include <cmath> using namespace std; #define rep(i,a,b) for(int i=(a);i<(b);++i) #define rrep(i,a,b) for(int i=(a);i>=(b);--i) #define clr(a,x) memset(a,(x),sizeof(a)); #define eps 1e-8 #define LL long long #define mp make_pair const int inf=1e8; const int maxn=60*12+5; struct Edge { int u,v,cost,cap,flow; Edge(int u,int v,int cost,int cap,int flow) :u(u),v(v),cost(cost),cap(cap),flow(flow) { } }; vector<Edge> edges; vector<int> G[maxn]; void add(int u,int v,int cap,int cost) { edges.push_back(Edge(u,v,cost,cap,0)); edges.push_back(Edge(v,u,-cost,0,0)); int m=edges.size(); G[u].push_back(m-2); G[v].push_back(m-1); } struct MCMF { int p[maxn],d[maxn]; bool inq[maxn]; int s,t,n; int Augment() { int a=inf,x=t; while(x!=s) { Edge&e=edges[p[x]]; a=min(a,e.cap-e.flow); x=e.u; } x=t; while(x!=s) { edges[p[x]].flow += a; edges[p[x]^1].flow -= a; x=edges[p[x]].u; } return a; } bool spfa(int&flow,int&cost) { clr(inq,0); rep(i,0,n) d[i]=inf; d[s]=0; queue<int> q; q.push(s); while(q.size()) { int u=q.front(); q.pop(); inq[u]=false; rep(i,0,G[u].size()) { Edge&e=edges[G[u][i]]; if(e.cap<=e.flow||d[e.v]<=d[u]+e.cost) continue; d[e.v]=d[u]+e.cost; p[e.v]=G[u][i]; if(!inq[e.v]) { inq[e.v]=true; q.push(e.v); } } } if(d[t]==inf) return false; int a = Augment(); flow += a; cost += d[t]*a; return true; } void init(int n) { this->n=n; } int mincost(int s,int t) { this->s=s; this->t=t; int flow=0,cost=0; while(spfa(flow,cost)); return cost; } }solver; int s,t,n,m; int cost[66][66]; void input() { rep(i,0,n) rep(j,0,m) scanf("%d",&cost[i][j]); rep(i,0,maxn) G[i].clear(); edges.clear(); s=0; t=n*m+n+1; solver.init(t+1); rep(i,1,n+1) add(n*m+i,t,1,0); rep(i,0,m) { rep(j,1,n+1) { add(s,i*n+j,1,0); rep(k,1,n+1) { add(i*n+j,n*m+k,1,cost[k-1][i]*j); } } } } void solve() { int cost=solver.mincost(s,t); printf("%.2lf\n",(double)cost/n); } int main() { while(scanf("%d%d",&m,&n)==2) { input(); solve(); } }
相关文章推荐
- [BZOJ1070][SCOI2007]修车-最小费用流
- 【bzoj1070】[SCOI2007]修车 最小费用流
- BZOJ 1070 [SCOI2007]修车 最小费用流
- bzoj 1070 [SCOI2007]修车(最小费用最大流)
- 【最小费用最大流】BZOJ1070 [SCOI2007]修车
- bzoj1070 [SCOI2007]修车 费用流
- bzoj1070 [SCOI2007]修车
- BZOJ 1070 [SCOI2007]修车
- bzoj1070 [SCOI2007]修车
- bzoj 1070: [SCOI2007]修车
- bzoj 1070 [SCOI2007]修车
- 1070: [SCOI2007]修车 - BZOJ
- BZOJ 1070: [SCOI2007]修车
- bzoj 1070: [SCOI2007]修车 费用流
- bzoj 1070 [SCOI2007]修车(最小费用最大流)
- 【BZOJ1070】[SCOI2007]修车 费用流
- bzoj1070 [SCOI2007]修车
- [bzoj1070][SCOI2007]修车【费用流】
- 【网络流】【BZOJ1070】【SCOI2007】修车
- bzoj 1070: [SCOI2007]修车(费用流)[省选计划系列]