Kattis - applemarket Apple Market (ST表+最大流)

题意:一个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=1; i<=n; ++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 }

 

posted @ 2020-04-12 20:32  jrltx  阅读(208)  评论(0编辑  收藏  举报