zoukankan      html  css  js  c++  java
  • bzoj1070 [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)

     
    听说这题也是经典题……为什么我见到的都是经典题
    考虑第i个人修理第k辆车,后面还有j-1个人等着的情况。代价就是j*cost[k,i]
    把所有维修人员拆点,拆成n*m个。点(i,j)表示第i个人在修倒数第j辆车,那么某辆车k向点(i,j)连的边,费用就是j*coss[k,i]
    然后S向所有车连边,所有车分别向n*m个点连边,n*m个点向T连边
    #include<cstdio>
    #include<iostream>
    #define LL long long
    #define inf 0x3fffffff
    #define S 0
    #define T 1001
    #define N 1010
    #define p(x,y) (x-1)*m+y
    using namespace std;
    inline LL read()
    {
        LL 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*10+ch-'0';ch=getchar();}
        return x*f;
    }
    struct edge{int to,next,v,c,from;}e[100*N];
    int head[N],dist[N],q[N],from[N];
    int a[N][N];
    bool mrk[N];
    int n,m,cnt=1,ans;
    inline void ins(int u,int v,int w,int c)
    {
        e[++cnt].to=v;
        e[cnt].v=w;
        e[cnt].c=c;
        e[cnt].from=u;
        e[cnt].next=head[u];
        head[u]=cnt;
    }
    inline void insert(int u,int v,int w,int c)
    {
        ins(u,v,w,c);
        ins(v,u,0,-c);
    }
    inline bool spfa()
    {
        for (int i=0;i<=T;i++)dist[i]=inf;
        int t=0,w=1;
        dist[S]=0;q[0]=S;mrk[S]=1;
        while (t!=w)
        {
            int now=q[t++];if (t==N-1)t=0;
            for (int i=head[now];i;i=e[i].next)
                if (e[i].v&&dist[now]+e[i].c<dist[e[i].to])
                {
                    dist[e[i].to]=dist[now]+e[i].c;
                    from[e[i].to]=i;
                    if (!mrk[e[i].to])
                    {
                        mrk[e[i].to]=1;
                        q[w++]=e[i].to;
                        if (w==N-1)w=0;
                    }
                }
            mrk[now]=0;
        }
        return dist[T]!=inf;
    }
    inline void mcf()
    {
        int x=inf;
        for (int i=from[T];i;i=from[e[i].from])
            x=min(x,e[i].v);
        for (int i=from[T];i;i=from[e[i].from])
        {
            e[i].v-=x;
            e[i^1].v+=x;
            ans+=x*e[i].c;
        }
    }
    int main()
    {
        m=read();n=read();
        for (int i=1;i<=n;i++)
            for (int j=1;j<=m;j++)
                a[i][j]=read();
        for (int i=1;i<=n;i++)insert(S,i,1,0);
        for (int i=1;i<=n;i++)
            for (int j=1;j<=m;j++)
            {
                for (int k=1;k<=n;k++)
                    insert(i,n+p(k,j),1,(n-k+1)*a[i][j]);
                insert(n+p(i,j),T,1,0);
            }
        while (spfa())mcf();
        printf("%.2lf
    ",(double)ans/n);
    }
    
    ——by zhber,转载请注明来源
  • 相关阅读:
    正则表达式
    .net打印控件基本用法
    批处理
    dos命令
    网络散点
    华为路由器命令
    用eNSP模拟
    oracle PL/SQL语法基础
    路由
    docker redis shell
  • 原文地址:https://www.cnblogs.com/zhber/p/4216197.html
Copyright © 2011-2022 走看看