[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 }