zoukankan      html  css  js  c++  java
  • 洛谷 P2053 [SCOI2007]修车 解题报告

    P2053 [SCOI2007]修车

    题目描述

    同一时刻有N位车主带着他们的爱车来到了汽车维修中心。维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的。现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小。

    说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间。

    输入输出格式

    输入格式:

    第一行有两个数M,N,表示技术人员数与顾客数。

    接下来n行,每行m个整数。第i+1行第j个数表示第j位技术人员维修第i辆车需要用的时间T。

    输出格式:

    最小平均等待时间,答案精确到小数点后2位。

    说明

    (2<=M<=9,1<=N<=60,1<=T<=1000)


    感觉费用流建模好难啊,也许是接触的少了?

    我们发现每个车要把前面修车的都等一遍,也就是说如果某个技术人员连续修理(c_1,c_2,..,c_n)这些车,等待的总时间其实是(w_1*n+w_2*(n-1)+...+w_n*1)

    我们可以把这些项分开处理。把每个修车的拆成车那么多个点,表示这个修车的在第几位给这个车子修车。

    可以把车和新的修车的点看成两个集合,即是二分图带权匹配。

    连边
    1.S连每个车,容1费0
    2.每个车连修车的点集,容1费层数*原始修车费用
    3.修车的点连T,容1费0

    还有一点,这样为什么保证了对于某个修车的(j)跑了第(i)层的点时前(i-1)层的点都跑过了呢?因为边权是正的跑最小费用最大流的时候贪心就一定先把费用比较小的跑掉了


    Code:

    #include <cstdio>
    #include <queue>
    #include <cstring>
    const int N=802;
    const int M=80010;
    const int inf=0x3f3f3f3f;
    int head[N],to[M],Next[M],edge[M],cost[M],cnt=1;
    void add(int u,int v,int w,int c)
    {
        to[++cnt]=v;edge[cnt]=w;cost[cnt]=c;Next[cnt]=head[u];head[u]=cnt;
        to[++cnt]=u;edge[cnt]=0;cost[cnt]=-c;Next[cnt]=head[v];head[v]=cnt;
    }
    int t,n,m;
    void init()
    {
        scanf("%d%d",&m,&n);//技术人员,车子数量
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                scanf("%d",&t);
                for(int k=1;k<=n;k++)
                    add(i,n+(k-1)*m+j,1,t*k);
            }
            add(0,i,1,0);
        }
        t=n+n*m+1;
        for(int j=1;j<=m;j++)
            for(int k=1;k<=n;k++)
                add(n+(k-1)*m+j,t,1,0);
    }
    int dep[N],dis[N],used[N],pre[N],ans;
    bool spfa()
    {
        memset(dis,0x3f,sizeof(dis));
        dis[0]=0;
        std::queue <int > q;
        q.push(0);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            used[u]=0;
            for(int i=head[u];i;i=Next[i])
            {
                int v=to[i];
                if(!dep[v]&&edge[i]&&dis[v]>dis[u]+cost[i])
                {
                    dis[v]=dis[u]+cost[i];
                    pre[v]=i;
                    if(!used[v]) {used[v]=1;q.push(v);}
                }
            }
        }
        return dis[t]!=inf;
    }
    void costflow()
    {
        while(spfa())
        {
            int mi=inf;
            ans+=dis[t];
            for(int now=t;now;now=to[pre[now]^1])
                mi=mi>edge[pre[now]]?edge[pre[now]]:mi;
            for(int now=t;now;now=to[pre[now]^1])
                edge[pre[now]]-=mi,edge[pre[now]^1]+=mi;
        }
    }
    int main()
    {
        init();
        costflow();
        printf("%.2lf",double(ans)/double(n));
        return 0;
    }
    
    

    2018.7.14

  • 相关阅读:
    将vue文件script代码抽取到单独的js文件
    git pull 提示错误:Your local changes to the following files would be overwritten by merge
    vue和uniapp 配置项目基础路径
    XAMPP Access forbidden! Access to the requested directory is only available from the local network.
    postman与newman集成
    postman生成代码段
    Curl命令
    POST方法的Content-type类型
    Selenium Grid 并行的Web测试
    pytorch转ONNX以及TnesorRT的坑
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9310054.html
Copyright © 2011-2022 走看看