zhber
有好多做过的题没写下来,如果我还能记得就补吧

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\n",(double)ans/n);
}

 

posted on 2015-01-11 10:50  zhber  阅读(221)  评论(0编辑  收藏  举报