zoukankan      html  css  js  c++  java
  • bzoj3144 [Hnoi2013]切糕

    Description

    P

    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

    样例1:
    2 2 2
    1
    6 1
    6 1
    2 6
    2 6

    样例2:
    2 2 2
    0
    5 1
    5 1
    2 5
    2 5

    Sample Output

    样例1:
    6

    样例2:
    12

    Hint

    第一组样例中最佳切面的f为f(1,1)=f(2,1)=2,f(1,2)=f(2,2)=1。

    第二组样例中最佳切面的f为f(1,1)=f(2,1)=f(1,2)=f(2,2)=1。

    正解:最小割。

    这题连边很难啊,我只知道一个纵轴上的点要连起来,然后就没点思路了。。

    考虑如何将当前轴相邻的轴连边。如果当前点高度为k,那么就把当前点和相邻的高度为k-d的点相连。这样,我们就能在当前点与相邻点的[k-d,k+d]范围取一个最小值了。因为画图以后可以发现,这个范围形成了一个环,一个环的最大流肯定是环上的最小容量。这样,我们求出最大流以后,根据最小割最大流定理,我们求的也就是使得这个图不连通的最小割了。

     1 //It is made by wfj_2048~
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <complex>
     5 #include <cstring>
     6 #include <cstdlib>
     7 #include <cstdio>
     8 #include <vector>
     9 #include <cmath>
    10 #include <queue>
    11 #include <stack>
    12 #include <map>
    13 #include <set>
    14 #define inf (1<<30)
    15 #define il inline
    16 #define RG register
    17 #define ll long long
    18 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    19 
    20 using namespace std;
    21 
    22 struct edge{ int nt,to,flow,cap; }g[5000010];
    23 
    24 int head[100010],que[100010],d[100010],v[50][50][50],c[50][50][50],p,q,r,D,S,T,cnt,num=1;
    25 
    26 il int gi(){
    27     RG int x=0,q=1; RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    28     if (ch=='-') q=-1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x;
    29 }
    30 
    31 il void insert(RG int from,RG int to,RG int cap){ g[++num]=(edge){head[from],to,0,cap},head[from]=num; return; }
    32 
    33 il int bfs(RG int S,RG int T){
    34     memset(d,0,sizeof(d)); RG int h=0,t=1; que[t]=S,d[S]=1;
    35     while (h<t){
    36     RG int x=que[++h];
    37     for (RG int i=head[x];i;i=g[i].nt){
    38         RG int v=g[i].to;
    39         if (!d[v] && g[i].cap>g[i].flow){
    40         que[++t]=v,d[v]=d[x]+1;
    41         if (v==T) return 1;
    42         }
    43     }
    44     }
    45     return 0;
    46 }
    47 
    48 il int dfs(RG int x,RG int T,RG int a){
    49     if (x==T || !a) return a; RG int f,flow=0;
    50     for (RG int i=head[x];i;i=g[i].nt){
    51     RG int v=g[i].to;
    52     if (d[v]==d[x]+1 && g[i].cap>g[i].flow){
    53         f=dfs(v,T,min(a,g[i].cap-g[i].flow));
    54         g[i].flow+=f,g[i^1].flow-=f;
    55         flow+=f,a-=f; if (!a) return flow;
    56     }
    57     }
    58     if (!flow) d[x]=-1; return flow;
    59 }
    60 
    61 il int maxflow(RG int S,RG int T){ RG int flow=0; while (bfs(S,T)) flow+=dfs(S,T,inf); return flow; }
    62 
    63 il void work(){
    64     p=gi(),q=gi(),r=gi(),D=gi(),S=++cnt,T=++cnt;
    65     for (RG int i=1;i<=p;++i)
    66     for (RG int j=1;j<=q;++j)
    67         c[i][j][0]=++cnt,insert(S,c[i][j][0],inf),insert(c[i][j][0],S,0);
    68     for (RG int k=1;k<=r;++k)
    69     for (RG int i=1;i<=p;++i)
    70         for (RG int j=1;j<=q;++j) v[i][j][k]=gi(),c[i][j][k]=++cnt;
    71     for (RG int i=1;i<=p;++i)
    72     for (RG int j=1;j<=q;++j){
    73         for (RG int k=1;k<=r;++k){
    74         insert(c[i][j][k-1],c[i][j][k],v[i][j][k]),insert(c[i][j][k],c[i][j][k-1],0);
    75         if (i>1 && k>D) insert(c[i][j][k],c[i-1][j][k-D],inf),insert(c[i-1][j][k-D],c[i][j][k],0);
    76         if (i<p && k>D) insert(c[i][j][k],c[i+1][j][k-D],inf),insert(c[i+1][j][k-D],c[i][j][k],0);
    77         if (j>1 && k>D) insert(c[i][j][k],c[i][j-1][k-D],inf),insert(c[i][j-1][k-D],c[i][j][k],0);
    78         if (j<q && k>D) insert(c[i][j][k],c[i][j+1][k-D],inf),insert(c[i][j+1][k-D],c[i][j][k],0);
    79         }
    80         insert(c[i][j][r],T,inf),insert(T,c[i][j][r],0);
    81     }
    82     printf("%d
    ",maxflow(S,T)); return;
    83 }
    84 
    85 int main(){
    86     File("cake");
    87     work();
    88     return 0;
    89 }
  • 相关阅读:
    为啥我百度定位wifi可以定位准确,但用数据流量就给我定位到非洲西海岸
    利用BottomNavigationBar实现不同的fragment之间的转换
    VS2010中连接sql 2005连接问题microsoft.sqlserver.management.sdk.sfc
    zuul路由网关介绍及使用
    Hystrix断路器概述及使用
    Ribbon负载均衡概述及使用
    Eureka服务注册与发现 介绍及使用
    微服务介绍及springcloud入门概述
    springboot整合springdatajpa步骤及使用
    springboot整合shiro步骤
  • 原文地址:https://www.cnblogs.com/wfj2048/p/6440399.html
Copyright © 2011-2022 走看看