[BZOJ1070][SCOI2007]修车 费用流

Posted wls001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BZOJ1070][SCOI2007]修车 费用流相关的知识,希望对你有一定的参考价值。

1070: [SCOI2007]修车

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 6209  Solved: 2641
[Submit][Status][Discuss]

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

Sample Output

1.50

HINT

 

数据范围: (2<=M<=9,1<=N<=60), (1<=T<=1000)

 

 

我们先将所有m拆成n个点,每个点表示m倒数第i个维修的车。

对于每一辆车,我们向所有m拆的点连边,容量为1,费用为cost[i][j]*i表示他花的时间和后i个人等待的时间和。

跑最小费用最大流。

技术分享
 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<algorithm>
 7 #define maxn 700
 8 using namespace std;
 9 int n,m;
10 int a[100][100];
11 int t;
12 bool vis[maxn];
13 int dis[maxn];
14 struct data {
15     int to,next,c,w;
16 }e[maxn*maxn];
17 int head[maxn],cnt;
18 int q[maxn];
19 void add(int u,int v,int w,int c){e[cnt].next=head[u];e[cnt].to=v;e[cnt].c=c;e[cnt].w=w;head[u]=cnt++;}
20 int use=0;
21 bool spfa() {
22     for(int i=0;i<=t;i++) dis[i]=-214748364;
23     memset(vis,0,sizeof(vis));
24     int h=0,tail=1;
25     q[0]=t;
26     dis[t]=0;
27     vis[t]=1;
28     while(h!=tail) {
29         int now=q[h++];if(h==maxn) h=0;
30         for(int i=head[now];i>=0;i=e[i].next) {
31             int to=e[i].to;
32             if(e[i^1].w>0&&dis[to]<dis[now]+e[i].c) {
33                 dis[to]=dis[now]+e[i].c;
34                 if(!vis[to]){
35                     vis[to]=1;
36                     q[tail++]=to;if(tail==maxn) tail=0;
37                 }
38             }
39         }
40         vis[now]=0;
41     }
42     use-=dis[0];
43     return dis[0]!=-214748364;
44 }
45 int ans=0;
46 int dfs(int now,int af) {
47     if(now==t||af==0){ans+=use*af;return af;}
48     vis[now]=1;
49     int flow=0,f=0;
50     for(int i=head[now];i>=0;i=e[i].next) {
51         int to=e[i].to;
52         if(vis[to]) continue;
53         if(dis[to]==dis[now]+e[i].c&&e[i].w>0&&(f=dfs(to,min(af,e[i].w)))) {
54             e[i].w-=f;
55             e[i^1].w+=f;
56             flow+=f;
57             af-=f;
58             if(!af) break;
59         }
60     }
61     return flow;
62 }
63 void zkw() {
64     while(spfa()) {
65         do {
66             memset(vis,0,sizeof(vis));
67         }while(dfs(0,2147483647));
68         memset(vis,0,sizeof(vis));
69         use=0;
70     }
71 }
72 int main() {
73     memset(head,-1,sizeof(head));
74     scanf("%d%d",&m,&n);
75     for(int i=1;i<=n;i++)
76         for(int j=1;j<=m;j++) scanf("%d",&a[i][j]);
77     for(int i=1;i<=n;i++) {add(0,i,1,0);add(i,0,0,0);}
78     t=699;
79     for(int i=n+1;i<=n+n*m;i++) {add(i,t,1,0);add(t,i,0,0);}
80     for(int i=1;i<=n;i++) {
81         for(int j=n+1;j<=n+n*m;j++){
82             int cost=j-n;
83             int temp=cost/n+1;
84             cost%=n;
85             if(!cost) cost=n,temp--;
86             add(i,j,1,a[i][temp]*cost);
87             add(j,i,0,-a[i][temp]*cost);
88         }
89     }
90     zkw();
91     double ans1;
92     ans1=(double)ans/(double)n;
93     printf("%.2lf",ans1);
94 }
View Code

 








以上是关于[BZOJ1070][SCOI2007]修车 费用流的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 1070: [SCOI2007]修车 费用流

BZOJ 1070: [SCOI2007]修车

[BZOJ1070][SCOI2007]修车 费用流

bzoj 1070: [SCOI2007]修车

BZOJ1070[SCOI2007]修车

bzoj 1070: [SCOI2007]修车