bzoj 3144 切糕

题目大意:

一个立方体,每个点有一个值。

对于每个纵轴,都要选一个点使得选的点的总和最小且每个点与其所在纵轴相邻的纵轴的点的纵坐标之差的绝对值不能超过$d$

思路:

因为每个纵轴都只能选一个,考虑最小割

每个纵轴从S到T连一条链,对于每个限制:从一个链的点$i$向另一个链的$i-d$点连边,这样表示$x-y \geq d$

这样可以保证每一条从$S \rightarrow T$的链都被割且满足条件

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<vector>
 9 #include<map>
10 #include<set>
11 #define ll long long
12 #define db double
13 #define inf 2139062143
14 #define MAXN 65000
15 #define MAXM 290000
16 #define rep(i,s,t) for(register int i=(s),i##__end=(t);i<=i##__end;++i)
17 #define dwn(i,s,t) for(register int i=(s),i##__end=(t);i>=i##__end;--i)
18 #define ren for(register int i=fst[x];i;i=nxt[i])
19 #define Fill(x,t) memset(x,t,sizeof(x))
20 #define pls(a,b) (a+b)%MOD
21 #define mns(a,b) (a-b+MOD)%MOD
22 #define mul(a,b) (1LL*(a)*(b))%MOD
23 using namespace std;
24 inline int read()
25 {
26     int x=0,f=1;char ch=getchar();
27     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
28     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
29     return x*f;
30 }
31 int n,m,h,d,v[45][45][45];
32 const int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
33 struct Dinic
34 {
35     int fst[MAXN],nxt[MAXM<<1],to[MAXM<<1],cnt,val[MAXM<<1];
36     int vis[MAXN],q[MAXN],l,r,S,T,tot,dis[MAXN],cur[MAXN];
37     Dinic(){memset(fst,0,sizeof(fst));cnt=1,tot=0;}
38     void add(int u,int v,int w) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,val[cnt]=w;}
39     void ins(int u,int v,int w) {add(u,v,w);add(v,u,0);}
40     int bfs()
41     {
42         vis[T]=++tot,dis[T]=0,q[l=r=1]=T;int x;
43         while(l<=r)
44         {
45             x=q[l++],cur[x]=fst[x];ren if(val[i^1]&&vis[to[i]]!=tot)
46                 dis[to[i]]=dis[x]+1,vis[to[i]]=tot,q[++r]=to[i];
47         }
48         return vis[S]==tot;
49     }
50     int dfs(int x,int a)
51     {
52         if(x==T||!a) return a;int flw=0,f;
53         for(int& i=cur[x];i&&a;i=nxt[i])
54             if(val[i]&&dis[to[i]]==dis[x]-1&&(f=dfs(to[i],min(a,val[i]))))
55                 val[i]-=f,val[i^1]+=f,a-=f,flw+=f;
56         return flw;
57     }
58     int solve(int ss,int tt,int res=0)
59         {S=ss,T=tt;while(bfs()) res+=dfs(S,inf);return res;}
60 }D;
61 int t(int x,int y,int z) {return x*n*m+y*m+z-n*m-m-1;}
62 int ok(int x,int y) {return x&&y&&x<=n&&y<=m;}
63 int main()
64 {
65     n=read(),m=read(),h=read(),d=read();int ss=n*m*h,tt=ss+1,tx,ty;
66     rep(i,1,h) rep(j,1,n) rep(k,1,m) v[i][j][k]=read();
67     rep(j,1,n) rep(k,1,m) rep(i,1,h)
68         if(i>1) D.ins(t(i-1,j,k),t(i,j,k),v[i][j][k]);else D.ins(ss,t(i,j,k),v[i][j][k]);
69     rep(j,1,n) rep(k,1,m) rep(o,0,3) if(ok(tx=j+dx[o],ty=k+dy[o]))
70         rep(i,d+1,h) D.ins(t(i,j,k),t(i-d,tx,ty),inf);
71     rep(i,1,n) rep(j,1,m) D.ins(t(h,i,j),tt,inf);
72     printf("%d\n",D.solve(ss,tt));
73 }
View Code

 

posted @ 2019-04-18 13:41  jack_yyc  阅读(107)  评论(0编辑  收藏  举报