bzoj 1070[SCOI2007]修车 - 费用流

1070: [SCOI2007]修车

Time Limit: 1 Sec  Memory Limit: 128 MB

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)

 

对维修工拆点, 第k个维修工表示这辆车是他修的倒数k辆

对于 第 j 辆车连向第i个维修工的第k个节点的权值就是 k * a[i][j], 因为在他之后修的车都会加上等待的时间。

根据网络流的性质,他会优先跑小的边

所以跑费用流就是总的等待时间

 

 

  1 #include <iostream> 
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <queue>
  6 #define LL long long 
  7 
  8 using namespace std;
  9 
 10 queue<int> q;
 11 int cnt = 0;
 12 const int MAXN = 1e3;
 13 int ti;
 14 int dis[MAXN];
 15 int flag[MAXN];
 16 int head[MAXN];
 17 int N, M;
 18 int V;
 19 int S, T;
 20 int pre[MAXN];
 21 int e[MAXN];
 22 struct edge {
 23     int v;
 24     int next;
 25     int w;
 26     int cost;
 27 } g[600 * 600 * 10];
 28 
 29 double ans = 0;
 30 void addedge(int u, int v, int w, double cost)
 31 {
 32     g[cnt].v = v;
 33     g[cnt].w = w;
 34     g[cnt].cost = cost;
 35     g[cnt].next = head[u];
 36     head[u] = cnt++;
 37 }
 38 inline LL read()
 39 {
 40     LL x = 0, w = 1; char ch = 0;
 41     while(ch < '0' || ch > '9') {
 42         if(ch == '-') {
 43             w = -1;
 44         }
 45         ch = getchar();
 46     }
 47     while(ch >= '0' && ch <= '9') {
 48         x = x * 10 + ch - '0';
 49         ch = getchar();
 50     }
 51     return x * w;
 52 }
 53 
 54 bool SPFA()
 55 {
 56     while(!q.empty()) {
 57         q.pop();
 58     }
 59     memset(pre, 0, sizeof pre);
 60     memset(flag, 0, sizeof flag);
 61     memset(dis, 0x3f, sizeof dis);
 62     dis[0] = 0;
 63     q.push(S);
 64     while(!q.empty()) {
 65         int t = q.front();
 66         flag[t] = 0;
 67         q.pop();
 68         for(int j = head[t]; j != -1; j = g[j].next) {
 69             int to = g[j].v;
 70             if(dis[to] > dis[t] + g[j].cost && g[j].w > 0) {
 71                 dis[to] = dis[t] + g[j].cost;
 72             //    cout<<dis[to]<<endl;
 73                 pre[to] = t;
 74                 /*if(dis[to] < 0 && to == 0) {
 75                     for(int j = t; j ; j = pre[j]) {
 76                         cout<<j<<" "<<dis[j]<<endl;
 77                     }
 78                     cout<<endl;
 79                     exit(0);
 80                 }*/
 81                 e[to] = j;
 82                 if(!flag[to]) {
 83                     flag[to] = 1;
 84                     q.push(to);
 85                 }
 86             }
 87         }
 88     }
 89     if(!pre[T]) {
 90         return false;
 91     }
 92     ans += dis[T];
 93     int minflow = 1e9;
 94     for(int j = T; j; j = pre[j]) {
 95         //cout<<j<<" ";
 96         minflow = min(minflow, g[e[j]].w);
 97     }
 98     //cout<<endl;
 99     //cout<<dis[T]<<" "<<minflow<<endl<<endl;
100     for(int j = T; j; j = pre[j]) {
101         g[e[j]].w -= minflow;
102         g[e[j] ^ 1].w += minflow;
103     }
104     return true;
105 }
106 
107 int main()
108 {
109     memset(head, -1, sizeof head);
110     M = read(), N = read();
111     V = M * N;
112     S = 0, T = V + N + 1;
113     for(int i = 1; i <= N; i++) {
114         addedge(S, V + i, 1, 0);
115         addedge(V + i,S, 0, 0);
116         for(int j = 1; j <= M; j++) {
117             scanf("%d", &ti);
118             for(int t = 1; t <= N; t++) {
119                 addedge((t - 1) * M + j, V + i, 0, -1 * ti * t);
120                 addedge(V + i, (t - 1) * M + j, 1, 1 * ti * t);
121             }
122         }
123     }
124     for(int i = 1; i <= M * N; i++) {
125         addedge(i, T, 1, 0);
126         addedge(T, i, 0, 0);
127     }
128     while(SPFA()) {
129     }
130     printf("%.2lf\n", ans / N);
131     return 0;
132 }
133 
134 /*
135 2 2
136 3 2
137 1 4
138 
139 */
View Code

 

posted @ 2018-03-24 14:57  大财主  阅读(102)  评论(0编辑  收藏  举报