[bzoj1070][SCOI2007]修车[ 网络流]

把每个工人拆成N个点。记为A[i,j]表示第i个工人修倒数第j辆车.每个车跟所有N*M个工人拆出的点连边。流量为1,费用为$time[i,j]*k$。源和每辆车连边,N*M个点和汇连边,流量都为1,费用同为0。

  1 #include <iostream>
  2 #include <algorithm>
  3 #include <cstdio>
  4 #include <cstdlib>
  5 #include <cstring>
  6 #include <ctime>
  7 #include <cmath>
  8 #include <queue>
  9 
 10 using namespace std;
 11 
 12 template<const int _n,const int _m>
 13 struct Edge
 14 {
 15     struct Edge_base { int to,next,w,c; }e[_m]; int    cnt,p[_n];
 16     void    clear() { cnt=1,memset(p,0,sizeof(p)); }
 17     Edge() { clear(); }
 18     void    insert(const int x,const int y,const int z,const int zz)
 19     { e[++cnt].to=y; e[cnt].next=p[x]; e[cnt].w=z; e[cnt].c=zz; p[x]=cnt; return ; }
 20     void    link(const int x,const int y,const int z,const int zz)
 21     { insert(x,y,z,zz); insert(y,x,0,-zz); }
 22     int    start(const int x) { return p[x]; }
 23     Edge_base& operator[](const int x) { return e[x]; }
 24 };
 25 
 26 int    n,m,Time[61][10],SSS,TTT,Cost;
 27 int    Dis[610],cur[610];
 28 bool    visited[610];
 29 Edge<610,71000>e;
 30 
 31 bool    Spfa(const int S)
 32 {
 33     int    i,t,temp;
 34     queue<int>    Q;
 35     memset(Dis,0x3f,sizeof(Dis));
 36     Dis[S]=0;
 37     visited[S]=true;
 38     Q.push(S);
 39     while(!Q.empty())
 40     {
 41         t=Q.front();Q.pop();visited[t]=false;
 42         for(i=e.start(t);i;i=e[i].next)
 43         {
 44             temp=e[i].to;
 45             if(e[i].w && Dis[t]+e[i].c<Dis[temp])
 46             {
 47                 Dis[temp]=Dis[t]+e[i].c;
 48                 if(!visited[temp])
 49                 {
 50                     visited[temp]=true;
 51                     Q.push(temp);
 52                 }
 53             }
 54         }
 55     }
 56     return Dis[TTT]!=0x3f3f3f3f;
 57 }
 58 
 59 int    Dfs(const int S,const int bk)
 60 {
 61     visited[S]=true;
 62     if(S==TTT)return bk;
 63     int    rest=bk;
 64     for(int &i=cur[S];i;i=e[i].next)
 65     {
 66         if(!visited[e[i].to] && Dis[S]+e[i].c==Dis[e[i].to] && e[i].w)
 67         {
 68             int    flow=Dfs(e[i].to,min(rest,e[i].w));
 69             Cost+=flow*e[i].c;
 70             e[i].w-=flow;
 71             e[i^1].w+=flow;
 72             if((rest-=flow)<=0)break;
 73         }
 74     }
 75     if(bk==rest)Dis[S]=0x3f3f3f3f;
 76     return bk-rest;
 77 }
 78 
 79 int    Zkw()
 80 {
 81     while(Spfa(SSS))
 82     {
 83         do
 84         {
 85             memset(visited,0,sizeof(visited));
 86             memcpy(cur,e.p,sizeof(cur));
 87             Dfs(SSS,0x3f3f3f3f);
 88         }while(visited[TTT]);
 89     }
 90     return Cost;
 91 }
 92 
 93 int main()
 94 {
 95     int    i,j,k;
 96 
 97     scanf("%d%d",&n,&m);
 98     for(i=1;i<=m;++i)
 99         for(j=1;j<=n;++j)
100             scanf("%d",&Time[i][j]);
101     SSS=n*m+m+1,TTT=SSS+1;
102     for(i=1;i<=n*m;++i)e.link(SSS,i,1,0);
103     for(i=n*m+1;i<SSS;++i)e.link(i,TTT,1,0);
104     for(k=1;k<=m;++k)
105         for(i=1;i<=n;++i)
106             for(j=1;j<=m;++j)
107                 e.link((i-1)*m+j,n*m+k,1,Time[k][i]*j);
108     printf("%.2lf\n",(double)Zkw()/m);
109     return 0;
110 }

 

posted @ 2015-12-31 02:50  Gster  阅读(194)  评论(0编辑  收藏  举报