Submit: 1494 Solved: 818
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
Source
网络流 最小割
从底层到顶层连边,每条(x,y)纵轴成为一条链,其上边的容量等于割掉的花费,S连底层,顶层连T。
利用INF边限制D,求最小割。
http://blog.csdn.net/thy_asdf/article/details/50428973
↑这里讲得挺详细
1 /*by SilverN*/ 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #include<queue> 8 using namespace std; 9 const int INF=1e9; 10 const int mx[5]={0,1,0,-1,0}; 11 const int my[5]={0,0,1,0,-1}; 12 const int mxn=65010; 13 int read(){ 14 int x=0,f=1;char ch=getchar(); 15 while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} 16 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} 17 return x*f; 18 } 19 struct edge{ 20 int v,nxt,f; 21 }e[mxn<<4]; 22 int hd[mxn],mct=1; 23 void add_edge(int u,int v,int c){ 24 e[++mct].v=v;e[mct].f=c;e[mct].nxt=hd[u];hd[u]=mct;return; 25 } 26 void insert(int u,int v,int c){ 27 add_edge(u,v,c);add_edge(v,u,0);return; 28 } 29 int n,m,S,T; 30 int P,Q,R; 31 int w[45][45][45]; 32 int d[mxn]; 33 bool BFS(){ 34 memset(d,0,sizeof d); 35 d[S]=1; 36 queue<int>q; 37 q.push(S); 38 while(!q.empty()){ 39 int u=q.front();q.pop(); 40 for(int i=hd[u];i;i=e[i].nxt){ 41 int v=e[i].v; 42 if(!d[v] && e[i].f){ 43 d[v]=d[u]+1;q.push(v); 44 } 45 } 46 } 47 return d[T]; 48 } 49 int DFS(int u,int lim){ 50 if(u==T)return lim; 51 int tmp,f=0; 52 for(int i=hd[u];i;i=e[i].nxt){ 53 int v=e[i].v; 54 if(d[v]==d[u]+1 && e[i].f){ 55 tmp=DFS(v,min(lim,e[i].f)); 56 e[i].f-=tmp; 57 e[i^1].f+=tmp; 58 lim-=tmp; 59 f+=tmp; 60 if(!lim)return f; 61 } 62 } 63 d[u]=0; 64 return f; 65 } 66 int Dinic(){ 67 int res=0; 68 while(BFS())res+=DFS(S,1e9); 69 return res; 70 } 71 int id[45][45][45]; 72 void init(){ 73 int cnt=0; 74 for(int x=1;x<=P;x++) 75 for(int y=1;y<=Q;y++) 76 for(int z=1;z<=R;z++){ 77 id[x][y][z]=++cnt; 78 } 79 return; 80 } 81 int main(){ 82 P=read();Q=read();R=read(); 83 int i,j,k,D=read(); 84 init(); 85 S=0;T=P*Q*R+1; 86 for(i=1;i<=R;i++)//z 87 for(j=1;j<=P;j++)//x 88 for(k=1;k<=Q;k++){//y 89 w[j][k][i]=read(); 90 } 91 for(i=1;i<=P;i++)//x 92 for(j=1;j<=Q;j++){//y 93 for(k=1;k<=R;k++){//z 94 insert(id[i][j][k-1],id[i][j][k],w[i][j][k]); 95 if(k>D){ 96 int nx,ny; 97 for(int l=1;l<=4;l++){ 98 nx=i+mx[l]; 99 ny=j+my[l]; 100 if(nx<1 || nx>P || ny<1 || ny>Q)continue; 101 insert(id[i][j][k],id[nx][ny][k-D],INF); 102 } 103 } 104 } 105 insert(id[i][j][R],T,INF); 106 } 107 int ans=Dinic(); 108 printf("%d\n",ans); 109 return 0; 110 }