首页 > 代码库 > Bzoj1070 [SCOI2007]修车
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
2 2
3 2
1 4
3 2
1 4
Sample Output
1.50
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 }
Bzoj1070 [SCOI2007]修车
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。