P4231理发时间

来源:互联网 发布:易语言注册账号源码 编辑:程序博客网 时间:2024/04/27 14:47

问题描述

何老板开了一家理发店,店里有m名发型师。
今天,信竞班的n名同学一起同时来到何老板的店,每个同学都要理发,并且每个同学的发型要求都不相同。
每个发型师处理不同的发型所需时间可能不同。何老板想要给大家安排一个合理的理发顺序,使得大家等候的总时间最少。一个同学的等待时间是指从他到店开始到理发完毕所用的时间。

输入格式

第一行有两个整数m和n。
接下来一个n*m的整数矩阵,其中第i行第j列的数字表示第i号同学的发型由第j号理发师来处理所需的时间。

输出格式

一个整数,表示等候的最少总时间。

样例输入 1

2 2
3 2
1 4

样例输出 1

3

样例输入 2

3 9
42 2 53
16 66 94
37 55 99
77 79 11
9 2 95
19 49 10
5 19 91
36 14 95
100 61 54

样例输出 2

214

提示

对于100%的数据:2<=M<=10,1<=N<=100,1<=单个人理发的时间<=1000

题解

排队等候模型,将m个理发师拆成n个点,其中第k个点代表的是第n个人在倒数第k个所产生的时间消耗!!因为在其之后的每一个人都会产生多出的time[i][j]的时间消耗,所以从每个点向每个拆出的点连一条费用为time[i][j*k的边,容量为1,再从每个拆出的点向汇点连一条容量为1费用为0的边。
跑一次最小费用流。
注意数组范围至少100万!
注意spfa()中每取出一次front()数要取消mark,一开始怎么都调不对就是因为这。。

#include <stdio.h>#include <algorithm>#include <iostream>#include <cstring>#include <cstdio>#include <queue>using namespace std;#define maxn 1000009#define maxn1 1005#define inf 0xfffffffint n,m;int Next[maxn],End[maxn],Len[maxn],Last[maxn];int Con[maxn],path[maxn1*5],p2[maxn1*5];int ma[maxn1][maxn1];int dis[maxn1*5];int maxflow,mincost;int cnt=1;int st,en;bool mark[maxn1*5];queue<int>q;bool spfa(){    int i,j;    memset(mark,false,sizeof(mark));    memset(dis,0,sizeof(dis));    for(i=st;i<=en;i++) dis[i]=inf;    mark[st]=true;    q.push(st);    dis[st]=0;    while(q.size())    {        int x=q.front();        q.pop();        mark[x]=false;//弹出时要消除标记        for(i=Last[x];i;i=Next[i])        {            int en=End[i];            if(Con[i]>0&&dis[en]>dis[x]+Len[i])            {                dis[en]=dis[x]+Len[i];                path[en]=x;                p2[en]=i;                if(mark[en]==false)                {                    mark[en]=true;                    q.push(en);                }            }        }    }    if(dis[en]!=inf) return true;    else return false;}void insert(int x,int y,int z,int w){    cnt++;    Next[cnt]=Last[x];    Last[x]=cnt;    End[cnt]=y;    Len[cnt]=w;    Con[cnt]=z;}void addflow(){    int minn=inf,p=0;    for(int i=en;i;i=path[i])    {        p=p2[i];        minn=min(minn,Con[p]);    }    maxflow+=minn;    mincost+=minn*dis[en];    for(int i=en;i;i=path[i])    {        p=p2[i];        Con[p]-=minn;        Con[p^1]+=minn;    }}int main(){    scanf("%d%d",&m,&n);    int i,j,k;    for(i=1;i<=n;i++)    {        for(j=1;j<=m;j++)        {            scanf("%d",&ma[i][j]);        }    }    en=n+n*m+1;    for(i=1;i<=n;i++){        insert(0,i,1,0);        insert(i,0,0,0);    }    for(i=1;i<=n;i++)    {        for(j=1;j<=m;j++)        {            for(k=1;k<=n;k++)            {                int t=m*(k-1)+n+j;                insert(i,t,1,ma[i][j]*k);                insert(t,i,0,-ma[i][j]*k);            }           }    }    for(i=1;i<=m;i++)    {        for(j=1;j<=n;j++)        {            int t=m*(j-1)+n+i;            insert(t,en,1,0);            insert(en,t,0,0);        }     }    while(spfa()) addflow();    cout<<mincost;}