BZOJ3144 切糕

http://www.lydsy.com/JudgeOnline/problem.php?id=3144

思路:如果没有D的限制,那一个竖轴都是一个最小割,每个点向更高的点引一条流量为自己权值的边,那考虑D的情况,就表明在割i高度这条边的时候,不能割它相邻的i-d以下的任何边,因此,我们引一条边从i高度到相邻的i-d高度,流量为inf,这样就能维护D这个条件了

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<iostream>
 6 #define inf 0x7fffffff
 7 int d[5][5];
 8 int sz,id[50][50][50],S,T,nodes,P,Q,R,D;
 9 int tot,go[2000005],next[2000005],first[2000005],flow[2000005];
10 int op[2000005],dis[2000005],cnt[2000005],v[50][50][50];
11 int read(){
12     int t=0,f=1;char ch=getchar();
13     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
14     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
15     return t*f;
16 }
17 void insert(int x,int y,int z){
18     tot++;
19     go[tot]=y;
20     next[tot]=first[x];
21     first[x]=tot;
22     flow[tot]=z;
23 }
24 void add(int x,int y,int z){
25     insert(x,y,z);op[tot]=tot+1;
26     insert(y,x,0);op[tot]=tot-1;
27 }
28 int dfs(int x,int f){
29     if (x==T) return f;
30     int mn=nodes,sum=0;
31     for (int i=first[x];i;i=next[i]){
32         int pur=go[i];
33         if (flow[i]&&dis[pur]+1==dis[x]){
34             int F=std::min(f-sum,flow[i]);
35             int save=dfs(pur,F);
36             flow[i]-=save;
37             flow[op[i]]+=save;
38             sum+=save;
39             if (sum==f||dis[S]>=nodes) return sum;
40         }
41         if (flow[i]) mn=std::min(mn,dis[pur]);
42     }
43     if (sum==0){
44         cnt[dis[x]]--;
45         if (cnt[dis[x]]==0) dis[S]=nodes;
46         else {
47             dis[x]=mn+1;
48             cnt[dis[x]]++;
49         }
50     }
51     return sum;
52 }
53 int main(){
54     P=read();Q=read();R=read();
55     D=read();
56     for (int i=1;i<=R+1;i++)
57      for (int j=1;j<=P;j++)
58       for (int k=1;k<=Q;k++)
59        id[i][j][k]=++sz;
60     S=0;T=sz+1;nodes=T+1;   
61     for (int i=1;i<=R;i++)
62      for (int j=1;j<=P;j++)
63       for (int k=1;k<=Q;k++)
64        v[i][j][k]=read();   
65     for (int j=1;j<=P;j++)
66      for (int k=1;k<=Q;k++)
67       add(S,id[1][j][k],inf);
68     for (int j=1;j<=P;j++)
69      for (int k=1;k<=Q;k++)
70       add(id[R+1][j][k],T,inf);
71     for (int i=1;i<=R;i++)
72      for (int j=1;j<=P;j++)
73       for (int k=1;k<=Q;k++)
74        add(id[i][j][k],id[i+1][j][k],v[i][j][k]);
75     d[1][1]=d[2][2]=1;d[3][1]=d[4][2]=-1;
76     for (int i=1;i<=R;i++)
77      if (i>D)
78      for (int j=1;j<=P;j++)
79       for (int k=1;k<=Q;k++)
80         for (int l=1;l<=4;l++){
81             int dx=j+d[l][1],dy=k+d[l][2];
82             if (dx<1||dx>P||dy<1||dy>Q) continue;
83             add(id[i][j][k],id[i-D][dx][dy],inf);
84         }          
85     int ans=0;    
86     while (dis[S]<nodes) ans+=dfs(S,inf);
87     printf("%d\n",ans);
88     return 0;
89 }

 

posted @ 2016-06-28 07:49  GFY  阅读(184)  评论(0编辑  收藏  举报