1070: [SCOI2007]修车
2016-02-14 19:15
295 查看
1070: [SCOI2007]修车
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3691 Solved: 1491
[Submit][Status][Discuss]
Description
同一时刻有N位车主带着他们的爱车来到了汽车维修中心。维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的。现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小。 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间。Input
第一行有两个m,n,表示技术人员数与顾客数。 接下来n行,每行m个整数。第i+1行第j个数表示第j位技术人员维修第i辆车需要用的时间T。Output
最小平均等待时间,答案精确到小数点后2位。Sample Input
2 23 2
1 4
Sample Output
1.50HINT
数据范围: (2<=M<=9,1<=N<=60), (1<=T<=1000)Source
[Submit][Status][Discuss]
这题用网络流简直了。。。
将每个工人拆成n个点,分别代表第i个工人正在修倒数第j辆车将n辆车分别与这些点建边,费用为t[i][j]*k同时超级源超级汇等。。各边容量均为1,最后一遍最小费用最大流
为什么这样做呢?因为维修一辆车的时间只对其后面的维修造成影响,如果它是该工人修的倒数第k辆车,那么影响k次
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
using namespace std;
const int maxn = 70;
typedef double DB;
vector <int> v[maxn*maxn*maxn];
queue <int> q;
struct E{
int from,to,cap,flow,w;
}G[1000000];
DB cost = 0;
int n,m,cnt = 0,t[maxn][maxn],dis[maxn*maxn*maxn],fa[maxn*maxn*maxn],a[maxn*maxn*maxn];
bool vis[maxn*maxn*maxn];
void Add(int from,int to,int c,int w)
{
v[from].push_back(cnt); G[cnt++] = (E){from,to,c,0,w};
v[to].push_back(cnt); G[cnt++] = (E){to,from,0,0,-w};
}
bool spfa()
{
for (int i = 1; i <= m+n*m+1; i++) dis[i] = ~0U>>1,vis[i] = 0;
dis[0] = 0; vis[0] = 1; a[0] = ~0U>>1;
q.push(0);
while (!q.empty()) {
int k = q.front(); q.pop(); vis[k] = 0;
for (int i = 0; i < v[k].size(); i++) {
E e = G[v[k][i]];
if (e.cap > e.flow && dis[e.to] > dis[k] + e.w) {
dis[e.to] = dis[k] + e.w;
a[e.to] = min(a[k],e.cap - e.flow);
fa[e.to] = v[k][i];
if (!vis[e.to]) {
vis[e.to] = 1; q.push(e.to);
}
}
}
}
if (dis[m+m*n+1] == ~0U>>1) return 0;
int A = a[m+m*n+1];
cost += (DB)(A)*(DB)(dis[m+m*n+1]);
int u = m+m*n+1;
while (u) {
G[fa[u]].flow += A;
G[fa[u]^1].flow -= A;
u = G[fa[u]].from;
}
return 1;
}
int main()
{
#ifdef YZY
freopen("yzy.txt","r",stdin);
#endif
cin >> n >> m;
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
scanf("%d",&t[j][i]);
for (int i = 1; i <= m; i++) Add(0,i,1,0);
for (int i = 1; i <= m; i++)
for (int j = m+1; j <= m+n*m; j++) {
int w = (j-m-1)/m + 1;
int k = (j-m)%m; if (!k) k = m;
Add(i,j,1,t[w][i]*k);
}
for (int i = m+1; i <= m+n*m; i++) Add(i,m+n*m+1,1,0);
while (spfa());
printf("%.2f",cost/(DB)(m));
return 0;
}
相关文章推荐
- BZOJ-2190 仪仗队 数论+欧拉函数(线性筛)
- PHP:数组操作函数array_walk()和array_map()
- Oracle中session audsid的产生原理及含义
- Ubuntu 12.04LTS 直接蓝牙A2DP操作
- BZOJ-2190 仪仗队 数论+欧拉函数(线性筛)
- 【 bzoj 2661 】 [BeiJing wc2012]连连看 - 拆点费用流
- RGW Create bucket
- 1032. 挖掘机技术哪家强
- 如何清理Macbook垃圾文件
- 11. Container With Most Water LeetCode
- 关于在listView中优化的问题 更多方
- 网站复制
- C语言中的 (void*)0 与 (void)0
- Java认证考试实例疑难辨析(8)
- git中忽略UserInterfaceState.xcuserstate的方法
- VS调试ASP.NET浏览器会不断的发出POLL请求
- HDU 1709 The Balance(母函数)
- (一)利用processing创建基本图形
- HDU-1019-Least Common Multiple( 最大公约数 && 最小公倍数 && GCD )
- python开发学习-day05(正则深入、冒泡排序算法、自定义模块、常用标准模块)