Bzoj1070 [SCOI2007]修车
Submit: 5325 Solved: 2217
Description
同一时刻有N位车主带着他们的爱车来到了汽车维修中心。维修中心共有M位技术人员,不同的技术人员对不同
的车进行维修所用的时间是不同的。现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最
小。 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间。
Input
第一行有两个m,n,表示技术人员数与顾客数。 接下来n行,每行m个整数。第i+1行第j个数表示第j位技术人
员维修第i辆车需要用的时间T。
Output
最小平均等待时间,答案精确到小数点后2位。
Sample Input
3 2
1 4
Sample Output
HINT
数据范围: (2<=M<=9,1<=N<=60), (1<=T<=1000)
Source
网络流 费用流
……这题怎么这么像网络流?(悄悄百度)真是网络流啊………
把每个工人拆成n个点,这n个点分别向T连边,容量为1(同一时刻只能修一辆车),第i个点费用为i*(读入的花费)。
↑第i个点表示工人倒数第i个修这辆车,对总时间的贡献为等待的人数i*花费时间
跑费用流即可
1 /*by SilverN*/ 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #include<vector> 8 #include<queue> 9 using namespace std; 10 const int mxn=1010; 11 int read(){ 12 int x=0,f=1;char ch=getchar(); 13 while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} 14 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} 15 return x*f; 16 } 17 struct edge{ 18 int u,v,nxt,f,w; 19 }e[mxn*100]; 20 int hd[mxn],mct=1; 21 void add_edge(int u,int v,int f,int w){ 22 e[++mct].v=v; 23 e[mct].u=u; 24 e[mct].nxt=hd[u]; 25 e[mct].f=f;e[mct].w=w; 26 hd[u]=mct;return; 27 } 28 void insert(int u,int v,int f,int w){ 29 add_edge(u,v,f,w); add_edge(v,u,0,-w);return; 30 } 31 int S,T; 32 int dis[mxn],pre[mxn]; 33 int n,m; 34 queue<int>q; 35 bool inq[mxn]; 36 void SPFA(int s){ 37 memset(dis,0x3f,sizeof dis); 38 memset(pre,-1,sizeof pre); 39 dis[s]=0;q.push(s);inq[s]=1; 40 while(!q.empty()){ 41 int u=q.front();q.pop();inq[u]=0; 42 for(int i=hd[u];i;i=e[i].nxt){ 43 int v=e[i].v; 44 if(e[i].f && dis[v]>dis[u]+e[i].w){ 45 dis[v]=dis[u]+e[i].w; 46 pre[v]=i; 47 if(!inq[v]){ 48 inq[v]=1; 49 q.push(v); 50 } 51 } 52 } 53 } 54 return; 55 } 56 int mxflow(int s,int t){ 57 SPFA(s); 58 int res=0; 59 while(pre[t]!=-1){ 60 int tmp=0x3f3f3f3f; 61 for(int i=pre[t];i!=-1;i=pre[e[i].u]){ 62 tmp=min(tmp,e[i].f); 63 } 64 res+=dis[t]*tmp; 65 for(int i=pre[t];i!=-1;i=pre[e[i].u]){ 66 e[i].f-=tmp; 67 e[i^1].f+=tmp; 68 } 69 SPFA(s); 70 } 71 return res; 72 } 73 int main(){ 74 int i,j,w; 75 m=read();n=read(); 76 S=0;T=n+m*n+1; 77 for(i=1;i<=n;i++){ 78 insert(S,i,1,0); 79 } 80 for(i=1;i<=n;i++){ 81 for(j=1;j<=m;j++){ 82 w=read(); 83 for(int k=1;k<=n;k++){ 84 insert(i,j+n+m*(k-1),1,w*k); 85 } 86 } 87 } 88 for(i=1;i<=m;i++) 89 for(j=1;j<=n;j++) 90 insert(i+n+m*(j-1),T,1,0); 91 int ans=mxflow(S,T); 92 // printf("!! %d\n",ans); 93 printf("%.2f\n",(double)ans/n); 94 return 0; 95 }
上面那个跑了1000+ms,一看排行榜震惊了,怎么前面全是几十ms跑完的
在黄学长博客看到了神奇的zkw费用流,(看上去像是Dinic和SPFA的结合体),学习一下↓
这样写快了一半。
然而还是不知道几十ms怎么做到的啊
1 /*by SilverN*/ 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #include<vector> 8 #include<queue> 9 using namespace std; 10 const int mxn=1010; 11 int read(){ 12 int x=0,f=1;char ch=getchar(); 13 while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} 14 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} 15 return x*f; 16 } 17 struct edge{ 18 int u,v,nxt,f,w; 19 }e[mxn*100]; 20 int hd[mxn],mct=1; 21 void add_edge(int u,int v,int f,int w){ 22 e[++mct].v=v; 23 e[mct].u=u; 24 e[mct].nxt=hd[u]; 25 e[mct].f=f;e[mct].w=w; 26 hd[u]=mct;return; 27 } 28 void insert(int u,int v,int f,int w){ 29 add_edge(u,v,f,w); add_edge(v,u,0,-w);return; 30 } 31 int S,T; 32 int dis[mxn],pre[mxn]; 33 int n,m; 34 queue<int>q; 35 bool inq[mxn]; 36 bool mark[mxn]; 37 bool SPFA(int s){ 38 memset(inq,0,sizeof inq); 39 for(int i=0;i<=T;i++)dis[i]=0x3f3f3f3f; 40 dis[T]=0;q.push(T);inq[T]=1; 41 while(!q.empty()){ 42 int u=q.front();q.pop();inq[u]=0; 43 for(int i=hd[u];i;i=e[i].nxt){ 44 int v=e[i].v; 45 if(e[i^1].f && dis[v]>dis[u]-e[i].w){ 46 dis[v]=dis[u]-e[i].w; 47 // pre[v]=i; 48 if(!inq[v]){ 49 inq[v]=1; 50 q.push(v); 51 } 52 } 53 } 54 } 55 if(dis[S]==0x3f3f3f3f)return 0; 56 return 1; 57 } 58 int ans=0; 59 int DFS(int x,int f){ 60 if(x==T){inq[T]=1;return f;} 61 int used=0,w; 62 inq[x]=1; 63 for(int i=hd[x];i;i=e[i].nxt){ 64 int v=e[i].v; 65 if(!inq[v] && e[i].f && dis[x]-e[i].w==dis[v]){ 66 w=f-used; 67 w=DFS(v,min(e[i].f,w)); 68 ans+=w*e[i].w; 69 e[i].f-=w; e[i^1].f+=w; 70 used+=w; 71 if(used==f)return f; 72 } 73 } 74 return used; 75 } 76 77 void mxflow(int s,int t){ 78 while(SPFA(s)){ 79 inq[T]=1; 80 while(inq[T]){ 81 memset(inq,0,sizeof inq); 82 DFS(S,0x3f3f3f3f); 83 } 84 } 85 return; 86 } 87 int main(){ 88 int i,j,w; 89 m=read();n=read(); 90 S=0;T=n+m*n+1; 91 for(i=1;i<=n;i++){ 92 insert(S,i,1,0); 93 } 94 for(i=1;i<=n;i++){ 95 for(j=1;j<=m;j++){ 96 w=read(); 97 for(int k=1;k<=n;k++){ 98 insert(i,j+n+m*(k-1),1,w*k); 99 } 100 } 101 } 102 for(i=1;i<=m;i++) 103 for(j=1;j<=n;j++) 104 insert(i+n+m*(j-1),T,1,0); 105 mxflow(S,T); 106 printf("%.2f\n",(double)ans/n); 107 return 0; 108 }
转载于:https://www.cnblogs.com/SilverNebula/p/6517497.html
Bzoj1070 [SCOI2007]修车相关推荐
- bzoj1070: [SCOI2007]修车 网络流
bzoj1070: [SCOI2007]修车 Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同 的车进行维修所用的时间是不同的 ...
- bzoj1070: [SCOI2007]修车-费用流
Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使 ...
- bzoj1070: [SCOI2007]修车
本来想写美食节的..但是动态加点不会,今晚有点困,所以就写这题弱化版了. 然后做法就是把一个修理工拆成n个,表示倒数第几个修当前这辆车,这样做的原因就是修一部车的影响是对于后面的车的. 复习一波费用流 ...
- bzoj1070 [SCOI2007]修车 费用流+拆分
这个题一开始容易想到最暴力的建法,由于前面的决策影响后面的人的等待时间,所以就枚举第几个选第几辆, 由于有后面受前面影响,所以也可以看成前面对后面影响,影响的最多n个,所以就枚举影响建图,由于3辆车 ...
- luogu P2053 [SCOI2007]修车(费用流提前计算)
P2053 [SCOI2007]修车 要求平均时间最短,就等同于要求总时间最短. 一个人维修所花的时间,对同一位技术人员之后维修造成的影响是已知且固定的.那么,我们将费用提前计算.即将第 i 位车主的 ...
- 【BZOJ】1070: [SCOI2007]修车
1070: [SCOI2007]修车 Description 同 一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需 ...
- BZOJ 1070: [SCOI2007]修车(最小费用最大流)
建图很神奇..建完图其实就是裸的费用流了.. -------------------------------------------------------------- #include<cs ...
- BZOJ 1070: [SCOI2007]修车
1070: [SCOI2007]修车 Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要 ...
- luogu P2053 [SCOI2007]修车
P2053 [SCOI2007]修车 题目描述 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术 ...
- [SCOI2007]修车【最大流最小费用】
P2053 [SCOI2007]修车 这道题的思路当真是很不错了,首先,N和M都不是很大.(这是废话了) 然后,看到等修车的时间是一个和的形式,因为从某一时刻进去大家都在等,然后修了的第一批的人的消耗 ...
最新文章
- 从源代码编译里程碑的 ICS ROM
- 一个不错的命令行解析类
- 大数据学习——Storm集群搭建
- Android下常见的内存泄露
- 为什么hive需要mysql作为数据库_Hive安装(本地独立模式,MySql为元数据库)
- jsapi.php必须传openid,【微信统一支付】发起支付, returnCode != SUCCESS, returnMsg = JSAPI支付必须传openid...
- Linkify 添加链接
- Redis都有哪些监控指标,看完你就懂了!
- 深入解读MySQL8.0 新特性 :Crash Safe DDL 1
- 求翻转数循环结构C语言,[LeetCode Easy题快一起刷起来] 1. 两数之和 7. 整数翻转
- struts2源码分析-初始化流程
- 为什么使用事务?如何实现声明式事务?
- 阿里小姐姐工作7年,P6升P7无望,欲去当培训师
- flutter取消动态字体大小
- 变年轻特效怎么制作?这三个方法你值得收藏
- 解决H5安卓自带浏览器video层级问题
- 2021年牛宝宝起名取名,惊艳有诗意的三字女孩名
- linux下双网卡绑定,Linux下双网卡绑定bond0
- 【自学Python】Windows安装Python
- C语言中字符串的初始化