题意:一个n*m的矩形区域,每个点上都有一些苹果,有k个人要买苹果,每个人可以买某个矩形区域内的至多x个苹果,问最多能卖出去多少个苹果。(n,m<=50,k<=1e5)
最大流,建图需要用ST表优化,这样每个人至多只需与4个点相连就能确定一个矩形区域。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=50+10; 5 const ll inf=0x3f3f3f3f3f3f3f3fll; 6 int a[N][N],ST[N][N][10][10],lg[N],n,m,k,tot,S,T,id[(int)1e5+10]; 7 struct MF { 8 static const int N=1e7+10,M=1e7+10; 9 int hd[N],ne,cur[N],n; 10 ll d[N]; 11 struct E { 12 int v; 13 ll cp; 14 int nxt; 15 } e[M]; 16 void init(int _n) {memset(hd,-1,sizeof hd),ne=0,n=_n;} 17 void link(int u,int v,ll cp) { 18 e[ne]= {v,cp,hd[u]},hd[u]=ne++; 19 e[ne]= {u,0,hd[v]},hd[v]=ne++; 20 } 21 int bfs(int s,int t) { 22 queue<int> q; 23 memset(d,-1,sizeof d); 24 d[s]=0,q.push(s); 25 while(q.size()) { 26 int u=q.front(); 27 q.pop(); 28 for(int i=hd[u]; ~i; i=e[i].nxt)if(e[i].cp) { 29 int v=e[i].v; 30 if(!~d[v])d[v]=d[u]+1,q.push(v); 31 } 32 } 33 return ~d[t]; 34 } 35 ll dfs(int u,int t,ll f) { 36 if(u==t||!f)return f; 37 ll ret=0; 38 for(int& i=cur[u]; ~i; i=e[i].nxt) { 39 int v=e[i].v; 40 if(d[v]==d[u]+1) { 41 ll df=dfs(v,t,min(f,e[i].cp)); 42 e[i].cp-=df,e[i^1].cp+=df,f-=df,ret+=df; 43 if(!f)return ret; 44 } 45 } 46 return ret; 47 } 48 ll dinic(int s,int t) { 49 ll ret=0; 50 while(bfs(s,t)) { 51 for(int i=0; i<ne; ++i)cur[i]=hd[i]; 52 ret+=dfs(s,t,inf); 53 } 54 return ret; 55 } 56 } mf; 57 void upd(int u,int x1,int y1,int x2,int y2) { 58 int k=lg[x2-x1+1],l=lg[y2-y1+1]; 59 mf.link(ST[x1][y1][k][l],u,inf); 60 mf.link(ST[x1][y2-(1<<l)+1][k][l],u,inf); 61 mf.link(ST[x2-(1<<k)+1][y1][k][l],u,inf); 62 mf.link(ST[x2-(1<<k)+1][y2-(1<<l)+1][k][l],u,inf); 63 } 64 int main() { 65 lg[0]=-1; 66 for(int i=1; i<N; ++i)lg[i]=lg[i>>1]+1; 67 scanf("%d%d%d",&n,&m,&k); 68 for(int i=1; i<=n; ++i) 69 for(int j=1; j<=m; ++j)scanf("%d",&a[i][j]); 70 S=++tot,T=++tot; 71 for(int i=1; i<=k; ++i)id[i]=++tot; 72 for(int k=0; k<=lg[n]; ++k) 73 for(int l=0; l<=lg[m]; ++l) 74 for(int i=1; i+(1<<k)-1<=n; ++i) 75 for(int j=1; j+(1<<l)-1<=m; ++j) 76 ST[i][j][k][l]=++tot; 77 mf.init(tot); 78 for(int k=0; k<=lg[n]; ++k) 79 for(int l=0; l<=lg[m]; ++l) 80 for(int i=1; i+(1<<k)-1<=n; ++i) 81 for(int j=1; j+(1<<l)-1<=m; ++j) { 82 if(k) { 83 mf.link(ST[i][j][k-1][l],ST[i][j][k][l],inf); 84 mf.link(ST[i+(1<<(k-1))][j][k-1][l],ST[i][j][k][l],inf); 85 } else if(l) { 86 mf.link(ST[i][j][k][l-1],ST[i][j][k][l],inf); 87 mf.link(ST[i][j+(1<<(l-1))][k][l-1],ST[i][j][k][l],inf); 88 } 89 } 90 for(int i=1; i<=n; ++i) 91 for(int j=1; j<=m; ++j)mf.link(S,ST[i][j][0][0],a[i][j]); 92 for(int i=1; i<=k; ++i) { 93 int x1,x2,y1,y2,c; 94 scanf("%d%d%d%d%d",&x1,&x2,&y1,&y2,&c); 95 upd(id[i],x1,y1,x2,y2); 96 mf.link(id[i],T,c); 97 } 98 printf("%lld\n",mf.dinic(S,T)); 99 return 0; 100 }