BZOJ3144 [HNOI2013]切糕

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

这篇题解看了就懂:画图很形象,讲解很好懂,而且不啰嗦,它,值得信赖。

http://blog.csdn.net/thy_asdf/article/details/50428973

然后感觉我代码写的也还可以,虽然跑起来有点慢= =

#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const int maxn=42;
const int maxt=65000;
const int INF=0x3f3f3f3f;

struct Node{
    int data,next,low;
}node[maxt*4*2];

#define now node[point].data
#define then node[point].next
#define www node[point].low

int P,Q,R,D;
int s,t,cnt,Idex;
int head[maxt],cur[maxt];
int dis[maxt],que[maxt];
int a[maxn][maxn][maxn];
int ind[maxn][maxn][maxn];

void add(int u,int v,int w){
    node[cnt].data=v;node[cnt].next=head[u];node[cnt].low=w;head[u]=cnt++;
    node[cnt].data=u;node[cnt].next=head[v];node[cnt].low=0;head[v]=cnt++;
}

void kadd(int i,int j,int k,int to){
    if(ind[i+1][j][to]) add(ind[i][j][k],ind[i+1][j][to],INF);
    if(ind[i-1][j][to]) add(ind[i][j][k],ind[i-1][j][to],INF);
    if(ind[i][j+1][to]) add(ind[i][j][k],ind[i][j+1][to],INF);
    if(ind[i][j-1][to]) add(ind[i][j][k],ind[i][j-1][to],INF);
}

void iadd(int i,int j,int k,int to){
    if(ind[i+1][j][k]) add(ind[i+1][j][k],ind[i][j][to],INF);
    if(ind[i-1][j][k]) add(ind[i-1][j][k],ind[i][j][to],INF);
    if(ind[i][j+1][k]) add(ind[i][j+1][k],ind[i][j][to],INF);
    if(ind[i][j-1][k]) add(ind[i][j-1][k],ind[i][j][to],INF);
}

bool BFS(){
    memset(dis,-1,sizeof(dis));
    int H=0,T=1;que[1]=0;dis[0]=0;
    while(H<T){
        H++;
        for(int point=head[que[H]];point!=-1;point=then)
            if(www && dis[now]<0){
                dis[now]=dis[que[H]]+1;
                que[++T]=now;
            }
    }
    return dis[t]>0;
}

int dfs(int x,int low){
    if(x==t) return low;
    int Low;
    for(int &point=cur[x];point!=-1;point=then)
        if(www && dis[now]==dis[x]+1){
            Low=dfs(now,min(low,www));
            if(Low){
                www-=Low;node[point^1].low+=Low;
                return Low;
            }
        }
    return 0;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("3144.in","r",stdin);
    freopen("3144.out","w",stdout);
#endif

    scanf("%d%d%d%d",&P,&Q,&R,&D);
    for(int i=1;i<=R;i++)
        for(int j=1;j<=P;j++)
            for(int k=1;k<=Q;k++){
                scanf("%d",&a[j][k][i]);
            }
    for(int i=1;i<=P;i++)
        for(int j=1;j<=Q;j++)
            for(int k=1;k<R;k++)
                ind[i][j][k]=++Idex;
    t=1+Idex;
    for(int i=s;i<=t;i++) head[i]=-1;
    for(int i=1;i<=P;i++)
        for(int j=1;j<=Q;j++)
            ind[i][j][0]=s,ind[i][j][R]=t;
    for(int i=1;i<=P;i++)
        for(int j=1;j<=Q;j++)
            for(int k=0;k<R;k++){
                add(ind[i][j][k],ind[i][j][k+1],a[i][j][k+1]);
                if(k-D-1>0 && k) kadd(i,j,k-1,k-D-1);
                if(k+D<R && k) iadd(i,j,k+D,k);
            }
    
    int flag,ans=0;
    while(BFS()){
        for(int i=s;i<=t;i++) cur[i]=head[i];
        while(flag=dfs(s,INF))
            ans+=flag;
    }
    printf("%d",ans);
    return 0;
}
View Code
posted @ 2016-02-26 09:45  诚叙  阅读(241)  评论(0编辑  收藏  举报