【bzoj】 1070: [SCOI2007]修车
Description
同一时刻有N位车主带着他们的爱车来到了汽车维修中心。维修中心共有M位技术人员,不同的技术人员对不同
的车进行维修所用的时间是不同的。现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最
小。 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间。
Input
第一行有两个m,n,表示技术人员数与顾客数。 接下来n行,每行m个整数。第i+1行第j个数表示第j位技术人
员维修第i辆车需要用的时间T。
Output
最小平均等待时间,答案精确到小数点后2位。
Sample Input
2 2
3 2
1 4
3 2
1 4
Sample Output
1.50
HINT
数据范围: (2<=M<=9,1<=N<=60), (1<=T<=1000)
一个拆了很多很多点的网络流模型。(想法其实是先考虑一个修理师的情况,再考虑多个的情况)
把每个修理师拆成n个点,一辆车分别想着n个点连边,容量为1,费用为t * x 其中x = 1, 2, 3 ... n,表示在这之后修理车的人要总共等待t, t * 2, t * 3, t * 4...时间
然后跑一边最小费用最大流就可以了。
1 #include<queue> 2 #include<cstdio> 3 #include<iostream> 4 #define MAXN 100010 5 6 using namespace std; 7 8 const int INF=0x7fffffff; 9 10 int a[1010][1010],fee[MAXN],pre[MAXN]; 11 12 int n,m,src,decc,ans; 13 14 struct node { 15 int to; 16 int cost; 17 int next; 18 int val; 19 }; 20 node e[MAXN*2]; 21 22 int head[MAXN],tot=1; 23 24 bool vis[MAXN]; 25 26 queue<int> q; 27 28 inline void read(int&x) { 29 int f=1;x=0;char c=getchar(); 30 while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();} 31 while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-48;c=getchar();} 32 x=x*f; 33 } 34 35 inline void add(int x,int y,int val,int cost) { 36 e[++tot].to=y; 37 e[tot].val=val; 38 e[tot].cost=cost; 39 e[tot].next=head[x]; 40 head[x]=tot; 41 } 42 43 inline void add_edge(int x,int y,int val,int cost) { 44 add(x,y,val,cost); 45 add(y,x,0,-cost); 46 } 47 48 inline int min_flow() { 49 int flow=INF; 50 for(int i=pre[decc];i;i=pre[e[i^1].to]) 51 flow=min(flow,e[i].val); 52 for(int i=pre[decc];i;i=pre[e[i^1].to]) 53 e[i].val-=flow,e[i^1].val+=flow; 54 return flow; 55 } 56 57 inline bool spfa() { 58 for(int i=1;i<=decc;i++) fee[i]=INF; 59 fee[src]=0; 60 vis[src]=true; 61 while(!q.empty()) q.pop(); 62 q.push(src); 63 while(!q.empty()) { 64 int u=q.front(); 65 q.pop(); 66 vis[u]=false; 67 for(int i=head[u];i;i=e[i].next) { 68 int to=e[i].to; 69 if(fee[u]+e[i].cost<fee[to]&&e[i].val) { 70 fee[to]=fee[u]+e[i].cost; 71 pre[to]=i; 72 if(!vis[to]) { 73 q.push(to); 74 vis[to]=true; 75 } 76 } 77 } 78 } 79 return fee[decc]!=INF; 80 } 81 82 inline void build_graph() { 83 for(int i=1;i<=n;i++) 84 for(int j=1;j<=m;j++) 85 for(int k=1;k<=n;k++) 86 add_edge(i,j*n+k,1,a[i][j]*k); 87 src=n*m+n+1;decc=n*m+n+2; 88 for(int i=1;i<=n;i++) 89 add_edge(src,i,1,0); 90 for(int i=n+1;i<=n*m+n;i++) 91 add_edge(i,decc,1,0); 92 } 93 94 int main() { 95 read(m);read(n); 96 for(int i=1;i<=n;i++) 97 for(int j=1;j<=m;j++) 98 read(a[i][j]); 99 build_graph(); 100 while(spfa()) ans+=min_flow()*fee[decc]; 101 printf("%.2lf\n",(double)ans/n); 102 return 0; 103 }
作者:乌鸦坐飞机
出处:http://www.cnblogs.com/whistle13326/
新的风暴已经出现
怎么能够停止不前
穿越时空 竭尽全力
我会来到你身边
微笑面对危险
梦想成真不会遥远
鼓起勇气 坚定向前
奇迹一定会出现