[bzoj1070] [洛谷P2053] [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

Sample Output

1.50

HINT

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


想法

这道题还是挺经典的。

我们考虑到每个技术人员那里修车的人等待的总时间,发现那其实就是

\[
最后一个人修车时间 \times 1 + 倒数第二人修车时间 \times 2 + … + 第一人修车时间 \times x \(x表示到这个技术人员处修车的总人数)
\]

于是,我们把每个技术人员拆成n个点,代表某个技术人员修的第几辆车,共mn个点

每个顾客向这mn个点连边,边权为\(t \quad 2t \quad 3t \quad …\),容量为1

S向每个顾客连容量1费用0的边,那mn个点向T连容量1费用0的边。

跑一遍费用流即可。


代码

注意:输入时先输m再输n!!!

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>

#define INF 2100000000

using namespace std;

const int N = 81+65+81*65;

struct node{
    int v,f,c;
    node *next,*rev;
}pool[N*150],*h[N],*pree[N];
int cnt;
void addedge(int u,int v,int f,int c){
    node *p=&pool[++cnt],*q=&pool[++cnt];
    p->v=v;p->next=h[u];h[u]=p; p->f=f;p->c=c;p->rev=q;
    q->v=u;q->next=h[v];h[v]=q; q->f=0;q->c=-c;q->rev=p;
}

int S,T;
queue<int> que;
int vis[N],d[N],pre[N];
bool spfa(){
    int u,v;
    while(!que.empty()) que.pop();
    for(int i=S;i<=T;i++) d[i]=INF;
    d[S]=0; vis[S]=1; que.push(S);
    while(!que.empty()){
        u=que.front(); que.pop();
        vis[u]=0;
        for(node *p=h[u];p;p=p->next)
            if(p->f && d[v=p->v]>d[u]+p->c){
                d[v]=d[u]+p->c;
                pre[v]=u; pree[v]=p;
                if(!vis[v]) { vis[v]=1; que.push(v); }
            }
    }
    return d[T]!=INF;
}
int MCMF(){
    int f=0,c=0,u,w;
    while(spfa()){
        u=T; w=INF;
        while(u!=S){
            w=min(w,pree[u]->f);
            u=pre[u];
        }
        f+=w; c+=w*d[T];
        u=T;
        while(u!=S){
            pree[u]->f-=w;
            pree[u]->rev->f+=w;
            u=pre[u];
        }
    }
    return c;
}

int n,m;

int main()
{
    int x;
    scanf("%d%d",&m,&n); /**/

    S=0; T=m*n+n+1;
    for(int i=1;i<=n;i++){
        addedge(S,i,1,0);
        for(int j=1;j<=m;j++){
            scanf("%d",&x);
            for(int k=0;k<n;k++)
                addedge(i,n+k*m+j,1,x*(k+1));
        }
    }
    for(int i=1;i<=m;i++)
        for(int k=0;k<n;k++) addedge(n+k*m+i,T,1,0);
    double ans=MCMF();
    printf("%.2lf\n",ans/(double)n);

    return 0;
}

原文地址:https://www.cnblogs.com/lindalee/p/8638289.html

时间: 2024-10-16 04:15:40

[bzoj1070] [洛谷P2053] [SCOI2007] 修车的相关文章

洛谷 P2053 [SCOI2007]修车

题目描述 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小. 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间. 输入输出格式 输入格式: 第一行有两个数M,N,表示技术人员数与顾客数. 接下来n行,每行m个整数.第i+1行第j个数表示第j位技术人员维修第i辆车需要用的时间T. 输出格式: 最小平均等待时间,答案精确到小数点后2位

P2053 [SCOI2007]修车 费用流

https://www.luogu.org/problemnew/show/P2053 题意 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小. 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间. 思路 左边放n个点,表示n辆车.右边放m * n个点,表示m个工人,拆除n个点表示不同阶段.即如果第i辆车连上了第m个工人的第k个阶段

P2053 [SCOI2007]修车

思路 很妙的网络流题目 最开始我简单的想直接把n个车的点和m个人员的点直接用cap=t(i,j)的边连起来,显然是假的,因为没有考虑到车主等待的时间长度 然后考虑分析将\(w_1,w_2,\dots,w_k\)个车主对总时间的贡献,总的等待时间是\(\sum_{i=1}^kw_i\times (k-i+1)\)让一个人在第i个位置修车时对总时间的贡献是\((n-i+1)\times w_i\) 所以搞出n*m代表第m个维修人员在n的时候维修一辆车的贡献,然后连边就行了 代码 #include <

P2053 [SCOI2007]修车 最小费用最大流

题目描述 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小. 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间. 输入输出格式 输入格式: 第一行有两个数M,N,表示技术人员数与顾客数. 接下来n行,每行m个整数.第i+1行第j个数表示第j位技术人员维修第i辆车需要用的时间T. 输出格式: 最小平均等待时间,答案精确到小数点后2位

luogu P2053 [SCOI2007]修车 |费用流

题目描述 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小. 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间. 输入格式 第一行有两个数M,N,表示技术人员数与顾客数. 接下来n行,每行m个整数.第i+1行第j个数表示第j位技术人员维修第i辆车需要用的时间T. 输出格式 最小平均等待时间,答案精确到小数点后2位. #includ

洛谷 P2709 BZOJ 3781 小B的询问

题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数.小B请你帮助他回答询问. 输入输出格式 输入格式: 第一行,三个整数N.M.K. 第二行,N个整数,表示小B的序列. 接下来的M行,每行两个整数L.R. 输出格式: M行,每行一个整数,其中第i行的整数表示第i个询问的答案. 输入输出样例 输入样例#1: 6 4 3 1 3 2 1 1 3

洛谷1231 教辅的组成

洛谷1231 教辅的组成 https://www.luogu.org/problem/show?pid=1231 题目背景 滚粗了的HansBug在收拾旧语文书,然而他发现了什么奇妙的东西. 题目描述 蒟蒻HansBug在一本语文书里面发现了一本答案,然而他却明明记得这书应该还包含一份练习题.然而出现在他眼前的书多得数不胜数,其中有书,有答案,有练习册.已知一个完整的书册均应该包含且仅包含一本书.一本练习册和一份答案,然而现在全都乱做了一团.许多书上面的字迹都已经模糊了,然而HansBug还是可

[SCOI2007]修车

1070: [SCOI2007]修车 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 6007  Solved: 2559 [Submit][Status][Discuss] Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同 的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最 小. 说明:顾客的等待时间是指从他把车送至维修中心

洛谷教主花园dp

洛谷-教主的花园-动态规划 题目描述 教主有着一个环形的花园,他想在花园周围均匀地种上n棵树,但是教主花园的土壤很特别,每个位置适合种的树都不一样,一些树可能会因为不适合这个位置的土壤而损失观赏价值. 教主最喜欢3种树,这3种树的高度分别为10,20,30.教主希望这一圈树种得有层次感,所以任何一个位置的树要比它相邻的两棵树的高度都高或者都低,并且在此条件下,教主想要你设计出一套方案,使得观赏价值之和最高. 输入输出格式 输入格式: 输入文件garden.in的第1行为一个正整数n,表示需要种的