Bzoj3144 [Hnoi2013]切糕

Time Limit: 10 Sec  Memory Limit: 128 MB
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

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 }

 

posted @ 2016-12-31 20:24  SilverNebula  阅读(234)  评论(0编辑  收藏  举报
AmazingCounters.com