zoukankan      html  css  js  c++  java
  • Bzoj1070 [SCOI2007]修车

    Time Limit: 1 Sec  Memory Limit: 128 MB
    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

    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
    ",ans);
    93     printf("%.2f
    ",(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
    ",(double)ans/n);
    107     return 0;
    108 }
  • 相关阅读:
    《Java4Android视频教程》学习笔记(二)
    漫画
    MyEclipse启动时报 Unable to acquire application service. Ensure that the org.eclips
    linux下关闭桌面模式使用命令行模式及其它模式
    nginx 开启fastcgi 可支持php、python、perl等多种语言
    linux下安装ImageMagick和Imagick扩展
    nginx 平滑升级到Tengine并编译concat
    centos 安装详解
    for xml path group by
    泛型对象Lists转xml
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6517497.html
Copyright © 2011-2022 走看看