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; }