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;}
阅读全文
0 0
- P4231理发时间
- 理发
- 理发时间 2017信息学夏令营第三场
- 理发了
- 2015071204 - 理发
- 理发很麻烦
- 理发想到的
- 理发的感想
- 理发之感想
- 神奇的理发头盔
- 难忘的理发经历
- 理发·审美造型
- 优化:理发与学霸
- 西瓜理发记(一)
- 西瓜理发记(一)
- 西瓜理发记(二)
- [笑话] 男生女生理发后的区别
- 扬州三把刀之理发刀
- 为什么基类指针(或引用)可以调用派生类的private虚函数
- angular js 大小写转换
- typedef定义数组用法
- 一些linux命令
- 硅谷之谜
- P4231理发时间
- F
- 完全背包(背包九讲之2)
- python进程的通信:queue、进程池中的Queue
- python linux 后台运行问题解决
- 中考
- 约瑟夫环
- git
- LCT问题