1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<queue> 5 #define M 100005 6 #define S 100001 7 using namespace std; 8 int n,m,head[M],next[30*M],u[30*M],v[30*M],c[30*M],qi[30*M],a[M],tot,t[45][106],cnt=1,ans,d[M],f[M],from[M]; 9 void jia(int a1,int a2,int a3,int a4) 10 { 11 cnt++; 12 qi[cnt]=a1; 13 u[cnt]=a2; 14 v[cnt]=a3; 15 c[cnt]=a4; 16 next[cnt]=head[a1]; 17 head[a1]=cnt; 18 } 19 bool bfs() 20 { 21 for(int i=1;i<=S;i++) 22 d[i]=0x7fffffff; 23 queue<int>q; 24 q.push(0); 25 f[0]=1; 26 for(;!q.empty();) 27 { 28 int p=q.front(); 29 q.pop(); 30 f[p]=0; 31 for(int i=head[p];i;i=next[i]) 32 if(v[i]&&d[u[i]]>d[p]+c[i]) 33 { 34 d[u[i]]=d[p]+c[i]; 35 from[u[i]]=i; 36 if(!f[u[i]]) 37 { 38 q.push(u[i]); 39 f[u[i]]=1; 40 } 41 } 42 } 43 if(d[S]==0x7fffffff) 44 return 0; 45 else 46 return 1; 47 } 48 void wang() 49 { 50 int ma=0x7fffffff,x,y; 51 for(int i=from[S];i;i=from[qi[i]]) 52 { 53 ma=min(ma,v[i]); 54 if(qi[i]==0) 55 { 56 int a1=u[i]; 57 x=(a1-1)/tot+1; 58 y=a1%tot+1; 59 } 60 } 61 for(int i=from[S];i;i=from[qi[i]]) 62 { 63 v[i]-=ma; 64 v[i^1]+=ma; 65 ans+=c[i]*ma; 66 } 67 for(int i=1;i<=n;i++) 68 { 69 jia((x-1)*tot+y,m*tot+i,1,y*t[i][x]); 70 jia(m*tot+i,(x-1)*tot+y,0,-y*t[i][x]); 71 } 72 return; 73 } 74 int main() 75 { 76 scanf("%d%d",&n,&m); 77 for(int i=1;i<=n;i++) 78 { 79 scanf("%d",&a[i]); 80 tot+=a[i]; 81 } 82 for(int i=1;i<=n;i++) 83 for(int j=1;j<=m;j++) 84 scanf("%d",&t[i][j]); 85 for(int i=1;i<=m*tot;i++) 86 { 87 jia(0,i,1,0); 88 jia(i,0,0,0); 89 } 90 for(int i=1;i<=n;i++) 91 { 92 jia(m*tot+i,S,a[i],0); 93 jia(S,m*tot+i,0,0); 94 } 95 for(int i=1;i<=m;i++) 96 for(int j=1;j<=n;j++) 97 { 98 jia((i-1)*tot+1,m*tot+j,1,t[j][i]); 99 jia(m*tot+j,(i-1)*tot+1,0,-t[j][i]); 100 } 101 for(;bfs();) 102 wang(); 103 printf("%d",ans); 104 return 0; 105 }
同修车,不过要动态加点。