bzoj3144: [Hnoi2013]切糕
Description
Input
第一行是三个正整数P,Q,R,表示切糕的长P、 宽Q、高R。第二行有一个非负整数D,表示光滑性要求。接下来是R个P行Q列的矩阵,第z个 矩阵的第x行第y列是v(x,y,z) (1≤x≤P, 1≤y≤Q, 1≤z≤R)。
100%的数据满足P,Q,R≤40,0≤D≤R,且给出的所有的不和谐值不超过1000。
Output
仅包含一个整数,表示在合法基础上最小的总不和谐值。
Sample Input
2 2 2
1
6 1
6 1
2 6
2 6
1
6 1
6 1
2 6
2 6
Sample Output
6
HINT
最佳切面的f为f(1,1)=f(2,1)=2,f(1,2)=f(2,2)=1
题解:
http://blog.csdn.net/thy_asdf/article/details/50428973
code:
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #define maxn 41 7 #define maxnode maxn*maxn*maxn 8 #define inf 1061109567 9 using namespace std; 10 char ch; 11 bool ok; 12 void read(int &x){ 13 for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1; 14 for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar()); 15 if (ok) x=-x; 16 } 17 const int dx[4]={1,0,-1,0}; 18 const int dy[4]={0,1,0,-1}; 19 int a,b,c,v,n,d; 20 struct flow{ 21 int s,t,tot,now[maxnode],son[maxnode*5],pre[maxnode*5],val[maxnode*5]; 22 int head,tail,list[maxnode],dis[maxnode]; 23 bool bo[maxnode]; 24 void add(int a,int b,int c){pre[++tot]=now[a],now[a]=tot,son[tot]=b,val[tot]=c;} 25 void put(int a,int b,int c){add(a,b,c),add(b,a,0);} 26 void init(){tot=1,s=0,t=n+1;} 27 bool bfs(){ 28 memset(bo,0,sizeof(bo)); 29 head=0,tail=1,list[1]=s,dis[s]=0,bo[s]=1; 30 while (head!=tail){ 31 int u=list[++head]; 32 for (int p=now[u],v=son[p];p;p=pre[p],v=son[p]) 33 if (val[p]&&!bo[v]) dis[v]=dis[u]+1,bo[v]=1,list[++tail]=v; 34 } 35 return bo[t]; 36 } 37 int dfs(int u,int rest){ 38 if (u==t) return rest; 39 int ans=0; 40 for (int p=now[u],v=son[p];p&&rest;p=pre[p],v=son[p]) 41 if (val[p]&&dis[v]==dis[u]+1){ 42 int d=dfs(v,min(rest,val[p])); 43 val[p]-=d,val[p^1]+=d,ans+=d,rest-=d; 44 } 45 if (!ans) dis[u]=-1; 46 return ans; 47 } 48 int dinic(){ 49 int ans=0; 50 while (bfs()) ans+=dfs(s,inf); 51 return ans; 52 } 53 }f; 54 inline int calc(int y,int x,int z){return (z-1)*a*b+(y-1)*b+x;} 55 int main(){ 56 read(a),read(b),read(c),read(d),n=a*b*(c+1),f.init(); 57 for (int i=1;i<=a;i++) for (int j=1;j<=b;j++) f.put(0,calc(i,j,1),inf); 58 for (int k=1;k<=c;k++) for (int i=1;i<=a;i++) for (int j=1;j<=b;j++) 59 read(v),f.put(calc(i,j,k),calc(i,j,k+1),v); 60 for (int i=1;i<=a;i++) for (int j=1;j<=b;j++) f.put(calc(i,j,c+1),n+1,inf); 61 for (int i=1;i<=a;i++) for (int j=1;j<=b;j++) for (int k=d+1;k<=c+1;k++){ 62 for (int p=0;p<4;p++){ 63 int x=i+dx[p]; 64 if (!x||x>a) continue; 65 int y=j+dy[p]; 66 if (!y||y>b) continue; 67 f.put(calc(i,j,k),calc(x,y,k-d),inf); 68 } 69 } 70 printf("%d\n",f.dinic()); 71 return 0; 72 }