[HNOI2013]切糕

[HNOI2013]切糕

Time Limit: 10 Sec  Memory Limit: 128 MB

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 

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://www.cnblogs.com/Yuzao/p/7367429.html

 

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<cmath>
  6 #include<algorithm>
  7 #include<queue>
  8 #define inf (2e8)
  9 using namespace std;
 10 int head[70001],size=1,n,m,l,d,map[41][41][41],s=0,t,pos[41][41][41],cnt;
 11 struct node
 12 {
 13     int next,to,cap;
 14 }edge[700001];
 15 void putin(int from,int to,int cap)
 16 {
 17     size++;
 18     edge[size].next=head[from];
 19     edge[size].to=to;
 20     edge[size].cap=cap;
 21     head[from]=size;
 22 }
 23 void in(int from,int to,int cap)
 24 {
 25     putin(from,to,cap);
 26     putin(to,from,0);
 27 }
 28 int gi()
 29 {
 30     int ans=0,f=1;
 31     char i=getchar();
 32     while(i<'0'||i>'9'){if(i=='-')f=-1;i=getchar();}
 33     while(i>='0'&&i<='9'){ans=ans*10+i-'0';i=getchar();}
 34     return ans*f;
 35 }
 36 int dist[70001],numbs[70001],vis[70001];
 37 void bfs(int src,int des)
 38 {
 39     int i;
 40     for(i=0;i<=cnt+1;i++){dist[i]=cnt+2;numbs[i]=0;}
 41     dist[des]=0;
 42     numbs[0]=1;
 43     queue<int>mem;
 44     mem.push(des);
 45     while(!mem.empty())
 46     {
 47         int x=mem.front();mem.pop();
 48         vis[x]=0;
 49         for(i=head[x];i!=-1;i=edge[i].next)
 50         {
 51             int y=edge[i].to;
 52             if(edge[i].cap==0&&dist[y]==cnt+2)
 53             {
 54                 dist[y]=dist[x]+1;
 55                 numbs[dist[y]]++;
 56                 if(!vis[y])
 57                 {
 58                     mem.push(y);
 59                     vis[y]=1;
 60                 }
 61             }
 62         }
 63     }
 64 }
 65 int dfs(int root,int flow,int des)
 66 {
 67     if(root==des)return flow;
 68     int res=0,mindist=cnt+2;
 69     for(int i=head[root];i!=-1;i=edge[i].next)
 70     {
 71         if(edge[i].cap>0)
 72         {
 73             int y=edge[i].to;
 74             if(dist[root]==dist[y]+1)
 75             {
 76                 int tmp=dfs(y,min(flow-res,edge[i].cap),des);
 77                 edge[i].cap-=tmp;
 78                 edge[i^1].cap+=tmp;
 79                 res+=tmp;
 80                 if(dist[0]>=cnt+2)return res;
 81                 if(res==flow)break;
 82             }
 83             mindist=min(mindist,dist[y]+1);
 84         }
 85     }
 86     if(!res)
 87     {
 88         if(!(--numbs[dist[root]]))dist[0]=cnt+2;
 89         ++numbs[dist[root]=mindist];
 90     }
 91     return res;
 92 }
 93 int ISAP(int src,int des)
 94 {
 95     bfs(src,des);
 96     int f=0;
 97     while(dist[src]<cnt+2)
 98         f+=dfs(src,2e8,des);
 99     return f;
100 }
101 int main()
102 {
103     int i,j,k;
104     memset(head,-1,sizeof(head));
105     n=gi();m=gi();l=gi();d=gi();
106     for(i=1;i<=n;i++)
107         for(j=1;j<=m;j++)
108             pos[0][i][j]=++cnt;
109     for(i=1;i<=l;i++)
110         for(j=1;j<=n;j++)
111             for(k=1;k<=m;k++)
112                 map[i][j][k]=gi(),pos[i][j][k]=++cnt;
113     t=cnt+1;
114     for(i=1;i<=n;i++)
115         for(j=1;j<=m;j++)
116             in(s,pos[0][i][j],inf),in(pos[l][i][j],t,inf);
117     for(i=1;i<=l;i++)
118         for(j=1;j<=n;j++)
119             for(k=1;k<=m;k++)
120                 in(pos[i-1][j][k],pos[i][j][k],map[i][j][k]);
121     for(i=d+1;i<=l;i++)
122         for(j=1;j<=n;j++)
123             for(k=1;k<=m;k++)
124             {
125                 if(j>1)in(pos[i][j][k],pos[i-d][j-1][k],inf);
126                 if(j<n)in(pos[i][j][k],pos[i-d][j+1][k],inf);
127                 if(k>1)in(pos[i][j][k],pos[i-d][j][k-1],inf);
128                 if(k<m)in(pos[i][j][k],pos[i-d][j][k+1],inf);
129             }
130     int maxflow=0;
131     maxflow=ISAP(s,t);
132     printf("%d\n",maxflow);
133     return 0;
134 }

 

posted @ 2017-08-18 16:32  kakakakakaka  阅读(146)  评论(0编辑  收藏  举报

Never forget why you start

//鼠标爆炸特效