BZOJ 1070: [SCOI2007]修车

Posted You Siki

tags:

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

1070: [SCOI2007]修车

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 4983  Solved: 2049
[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)

 

Source

 
[Submit][Status][Discuss]

 

所有的点:

源点S

汇点T

N*M 第i名维修工,倒数第j次维修

N 第i辆汽车

 

所有的边:

S向N*M个拆分后的维修点,各连一条容量为1,费用为0的边。

每个汽车点向T连一条容量为1,费用为0的边。

第i名维修工在倒数第j次维修,修汽车k,造成的代价为 维修时间*j。

 

跑最小费用最大流。

 

  1 #include <bits/stdc++.h>
  2 
  3 #define fread_siz 1024
  4 
  5 inline int get_c(void)
  6 {
  7     static char buf[fread_siz];
  8     static char *head = buf + fread_siz;
  9     static char *tail = buf + fread_siz;
 10 
 11     if (head == tail)
 12         fread(head = buf, 1, fread_siz, stdin);
 13 
 14     return *head++;
 15 }
 16 
 17 inline int get_i(void)
 18 {
 19     register int ret = 0;
 20     register int neg = false;
 21     register int bit = get_c();
 22 
 23     for (; bit < 48; bit = get_c())
 24         if (bit == -)neg ^= true;
 25 
 26     for (; bit > 47; bit = get_c())
 27         ret = ret * 10 + bit - 48;
 28 
 29     return neg ? -ret : ret;
 30 }
 31 
 32 template <class T>
 33 inline T min(T a, T b)
 34 {
 35     return a < b ? a : b;
 36 }
 37 
 38 const int maxn = 500005;
 39 const int inf = 0x3f3f3f3f;
 40 
 41 int n, m;
 42 int s, t;
 43 int cost;
 44 int edges;
 45 int hd[maxn];
 46 int to[maxn];
 47 int nt[maxn];
 48 int vl[maxn];
 49 int fl[maxn];
 50 
 51 inline void add_edge(int u, int v, int f, int w)
 52 {    
 53     nt[edges] = hd[u]; to[edges] = v; fl[edges] = f; vl[edges] = +w; hd[u] = edges++;
 54     nt[edges] = hd[v]; to[edges] = u; fl[edges] = 0; vl[edges] = -w; hd[v] = edges++;
 55 }
 56 
 57 inline bool bfs(void)
 58 {
 59     static int dis[maxn];
 60     static int que[maxn];
 61     static int inq[maxn];
 62     static int pre[maxn];
 63     static int head, tail;
 64     
 65     memset(inq, 0, sizeof(inq));
 66     memset(dis, inf, sizeof(dis));
 67     
 68     head = 0, tail = 0;
 69     que[tail++] = s;
 70     pre[s] = -1;
 71     dis[s] = 0;
 72     inq[s] = 1;
 73     
 74     while (head != tail)
 75     {
 76         int u = que[head++], v; inq[u] = 0;
 77         
 78         if (head >= maxn)
 79             head = 0;
 80         
 81         for (int i = hd[u]; ~i; i = nt[i])
 82             if (fl[i] && dis[v = to[i]] > dis[u] + vl[i])
 83             {
 84                 dis[v] = dis[u] + vl[i], pre[v] = i^1; 
 85                 if (!inq[v])
 86                     inq[v] = 1, que[tail++] = v;
 87                 if (tail >= maxn)
 88                     tail = maxn;
 89             }
 90     }
 91 
 92     if (dis[t] >= inf)
 93         return false;
 94         
 95     int flow = inf;
 96     
 97     for (int i = pre[t]; ~i; i = pre[to[i]])
 98         if (flow > fl[i ^ 1])
 99             flow = fl[i ^ 1];
100             
101     for (int i = pre[t]; ~i; i = pre[to[i]])
102         fl[i] += flow, fl[i ^ 1] -= flow;
103         
104     cost += flow * dis[t];
105         
106     return true;
107 }
108 
109 inline void max_flow(void)
110 {
111     while (bfs());
112 }
113 
114 signed main(void)
115 {
116     n = get_i();
117     m = get_i();
118     
119     s = 0, t = n*m + m + 1;
120     
121     memset(hd, -1, sizeof(hd));
122     
123     for (int i = 1; i <= n*m; ++i)
124         add_edge(s, i, 1, 0);
125     
126     for (int i = 1; i <= m; ++i)
127         add_edge(i + n*m, t, 1, 0);
128         
129     for (int i = 1; i <= m; ++i)
130         for (int j = 1; j <= n; ++j)
131         {
132             int w = get_i();
133             for (int k = 1; k <= m; ++k)
134                 add_edge((j - 1)*m + k, n*m + i, 1, w*k); 
135         }
136         
137     max_flow();
138     
139     printf("%.2f\n", (float)cost / m);
140 }

 

@Author: YouSiki

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

BZOJ 1070: [SCOI2007]修车

bzoj 1070: [SCOI2007]修车 费用流

BZOJ 1070: [SCOI2007]修车

Bzoj1070--Scoi2007修车

[BZOJ1070][SCOI2007]修车 费用流

BZOJ1070[SCOI2007]修车