zoukankan      html  css  js  c++  java
  • P2053 [SCOI2007]修车

    传送门

    求最小平均等待时间就相当于求最小总等待时间

    考虑对于一个技术人员的修车顺序,$k_1,k_2,k_3,...,k_p$

    这 $p$ 辆车的车主的等待时间分别为 $t_{k_1},t_{k_1}+t_{k_2},t_{k_1}+t_{k_2}+t_{k_3},...,t_{k_1}+t_{k_2}+t_{k_3}+...+t_{k_p}$

    把同种的 $t$ 放在一起,考虑每种 $t$ 的贡献:$t_{k_1}*p,t_{k_2}*(p-1),t_{k_3}*(p-2),...,t_{k_p}*1$

    可以发现,如果车 $x$ 在修车顺序中为 $y$,总修车数为 $p$,那么 $x$ 的贡献就是 $t_x*(p-y+1)$

    倒过来,如果 $x$ 在倒过来的修车顺序中为 $y$,总修车数为 $p$,那么 $x$ 的贡献就是 $t_x*y$

    考虑构建这样一个费用流模型, $m$ 个技术人员拆成 $n$ 个点,每辆车往所有这些点连边,

    车 $x$ 连向第 $i$ 个技术人员的第 $j$ 个点的边表示,车 $x$ 可以选择让第 $i$ 个人倒数第 $j$ 个修

    那么对于每辆车 $x$ , $S$ 向 $x$ 连一条流量为 $1$,费用为 $0$ 的边,表示这种车只有一辆

    每辆车 $x$ 向所有技术人员的 $m*n$ 个点 $y$(设此点表示第 $i$ 个人倒数第 $j$ 个修 )连边,流量为 $1$,费用为 $cst[i][x]*j$($cst[i][x]$ 表示第 $i$ 个人修第 $x$ 辆车需要的时间)

    对于所有技术人员的 $m*n$ 个点,向 $T$ 一条流量为 $1$,费用 $0$ 的边

    然后最小费用最大流就是答案了

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<queue>
    using namespace std;
    typedef long long ll;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    const int N=2e5+7,INF=1e9+7;
    int fir[N],from[N<<1],to[N<<1],val[N<<1],cst[N<<1],cntt=1;
    inline void add(int a,int b,int c,int d)
    {
        from[++cntt]=fir[a]; fir[a]=cntt;
        to[cntt]=b; val[cntt]=c; cst[cntt]=d;
        from[++cntt]=fir[b]; fir[b]=cntt;
        to[cntt]=a; val[cntt]=0; cst[cntt]=-d;
    }
    int mif[N],pre[N],dis[N],S,T;
    bool inq[N];
    queue <int> q;
    bool BFS()
    {
        for(int i=S;i<=T;i++) dis[i]=INF;
        q.push(S); dis[S]=0; inq[S]=1; mif[S]=INF;
        while(!q.empty())
        {
            int x=q.front(); q.pop(); inq[x]=0;
            for(int i=fir[x];i;i=from[i])
            {
                int &v=to[i]; if( !val[i] || dis[v]<=dis[x]+cst[i] ) continue;
                dis[v]=dis[x]+cst[i]; pre[v]=i;
                mif[v]=min(mif[x],val[i]);
                if(!inq[v]) q.push(v),inq[v]=1;
            }
        }
        return dis[T]<INF;
    }
    int ans;
    void upd()
    {
        for(int now=T,i=pre[T]; now!=S; now=to[i^1],i=pre[now])
            val[i]-=mif[T],val[i^1]+=mif[T];
        ans+=mif[T]*dis[T];
    }
    
    int m,n,nm;
    int main()
    {
        m=read(),n=read(); int t;
        nm=n*m; S=0,T=nm+n+1;
        for(int i=1;i<=n;i++) add(S,nm+i,1,0);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                t=read();
                for(int k=1;k<=n;k++)
                    add(nm+i,(j-1)*n+k,1,t*k);
            }
        for(int i=1;i<=m;i++)
            for(int j=1;j<=n;j++) add((i-1)*n+j,T,1,0);
        while(BFS()) upd();
        printf("%.2lf",1.0*ans/n);
        return 0;
    }
  • 相关阅读:
    Zookeeper 笔记
    个人学习笔记
    VS Window窗体 (C#)程序 连接sql server 数据库
    每周总结 11.9~11.15
    需求分析 第七稿 功能实现进度09
    数据简单清洗和图标联动展示
    IDEA创建文件自动添加作者名及时间
    springcloudalibaba中文文档
    ContractHolder.parseAndValidateMetadata(Ljava/lang/Class;)Ljava/util/List;
    Sentinel fallback失效
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/10761486.html
Copyright © 2011-2022 走看看