[bzoj3144][Network flow-minimum cut]Cut cake

Description

write picture description here

Input

The first line is three positive integers P, Q, R, which represent the length P, width Q, and height R of the cake. The second line has a non-negative integer D representing the smoothness requirement. Next is R matrices with P rows and Q columns, and the xth row and yth column of the zth
matrix is ​​v(x,y,z) (1≤x≤P, 1≤y≤Q, 1≤z≤R ).
100% of the data satisfy P, Q, R≤40, 0≤D≤R, and all given dissonance values ​​do not exceed 1000.

Output

Contains only an integer representing the smallest total dissonance value on a legal basis.

Sample Input

2 2 2

1

6 1

6 1

2 6

2 6

Sample Output

6

HINT

The f of the best section is f(1,1)=f(2,1)=2, f(1,2)=f(2,2)=1

answer

Wow, I didn't think of doing the smallest cut like this during the exam. .
YY has a minimum cut with a certain full flow = =
For each vertical axis, each point is connected to the point above it, and the flow is the dissonance value of the point below.
For a point with a height of i, to the height of its surroundings Connect the edge to the point of iD, the flow INF
st is connected to each point on the bottom surface, and
each point (extended by one face) of the flow INF top surface is connected to the edge of ed, and the flow INF
can run the minimum cut.
Imagine , cut the vertical axis One edge is equivalent to selecting this point, then the point with the relative height > D to the other surrounding areas will be cut off, otherwise there will be an augmented path to flow. The assumption
here is that the selected point is higher, if The same is true if you choose a lower one, because another point can also be considered in the same way.

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const int dx[4]={0,-1,0,1};
const int dy[4]={-1,0,1,0};
struct node
{
    int x,y,c,next,other;
}a[810000];int len,last[210000];
void ins(int x,int y,int c)
{
    int k1,k2;
    k1=++len;
    a[len].x=x;a[len].y=y;a[len].c=c;
    a[len].next=last[x];last[x]=len;
    k2=++len;
    a[len].x=y;a[len].y=x;a[len].c=0;
    a[len].next=last[y];last[y]=len;
    a[k1].other=k2;
    a[k2].other=k1;
}
int h[110000],head,tail;
int list[2110000],st,ed;
bool bt_h()
{
    list[1]=st;head=1;tail=2;
    memset(h,0,sizeof(h));h[st]=1;
    while(head!=tail)
    {
        int x=list[head];
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(a[k].c>0 && h[y]==0)
            {
                h[y]=h[x]+1;
                list[tail++]=y;
            }
        }
        head++;
    }
    if(h[ed]==0)return false;
    return true;
}
int findflow(int x,int f)
{
    if(x==ed)return f;
    int s=0,t;
    for(int k=last[x];k;k=a[k].next)
    {
        int y=a[k].y;
        if(h[y]==h[x]+1 && a[k].c>0 && s<f)
        {
            s+=(t=findflow(y,min(a[k].c,f-s)));
            a[k].c-=t;a[a[k].other].c+=t;
        }
    }
    if(s==0)h[x]=0;
    return s;
}
int P,Q,R,D;
bool chk(int x,int y){if(x>=1 && x<=P && y>=1 && y<=Q)return true;return false;}
int val[45][45][45];
int pt(int x,int y,int z){return (z-1)*P*Q+(x-1)*Q+y;}
int main()
{
//  freopen("d.in","r",stdin);
//  freopen("d.out","w",stdout);
    scanf("%d%d%d",&P,&Q,&R);
    scanf("%d",&D);
    st=P*Q*(R+1)+1;ed=P*Q*(R+1)+2;
    for(int i=1;i<=R;i++)
        for(int j=1;j<=P;j++)
            for(int k=1;k<=Q;k++)scanf("%d",&val[j][k][i]),ins(pt(j,k,i),pt(j,k,i+1),val[j][k][i]);
    for(int i=D+1;i<=R;i++)
        for(int j=1;j<=P;j++)
            for(int k=1;k<=Q;k++)
                for(int l=0;l<=3;l++)
                    if(chk(j+dx[l],k+dy[l]))
                        ins(pt(j,k,i),pt(j+dx[l],k+dy[l],i-D),999999999);
    for(int i=1;i<=P;i++)for(int j=1;j<=Q;j++)ins(st,pt(i,j,1),999999999),ins(pt(i,j,R+1),ed,999999999);
    int ans=0;
    while(bt_h())ans+=findflow(st,99999999);
    printf("%d\n",ans);
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324706006&siteId=291194637