zoukankan      html  css  js  c++  java
  • 3144:[HNOI2013]切糕

    题目描述 Description
    经过千辛万苦小 A 得到了一块切糕,切糕的形状是长方体,小 A 打算拦腰将切糕切成两半分给小 B。出于美观考虑,小 A 希望切面能尽量光滑且和谐。于是她找到你,希望你能帮她找出最好的切割方案。 
    出于简便考虑,我们将切糕视作一个长 P、宽 Q、高 R 的长方体点阵。我们将位于第 z层中第 x 行、第 y 列上(1≤x≤P, 1≤y≤Q, 1≤z≤R)的点称为(x,y,z),它有一个非负的不和谐值 v(x,y,z)。一个合法的切面满足以下两个条件: 
    1. 与每个纵轴(一共有 P*Q 个纵轴)有且仅有一个交点。即切面是一个函数 f(x,y),对于所有 1≤x≤P, 1≤y≤Q,我们需指定一个切割点 f(x,y),且 1≤f(x,y)≤R。 
    2. 切面需要满足一定的光滑性要求,即相邻纵轴上的切割点不能相距太远。对于所有的 1≤x,x’≤P 和 1≤y,y’ ≤Q,若|x-x’|+|y-y’|=1,则|f(x,y)-f(x’,y’)| ≤D,其中 D 是给定的一个非负整数。 
    可能有许多切面f 满足上面的条件,小A 希望找出总的切割点上的不和谐值最小的那个,即 ∑v(x,y, f(x,y))最小。
    输入描述 Input Description
    输入文件第一行是三个正整数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)。
    输出描述 Output Description
    输出仅包含一个整数,表示在合法基础上最小的总不和谐值。
    样例输入 Sample Input
    input1
    2 2 2 
    6 1 
    6 1 
    2 6 
    2 6 
    input2 
    2 2 2 
    5 1 
    5 1 
    2 5 
    2 5
    样例输出 Sample Output
    output1
    output2
    12
    数据范围及提示 Data Size & Hint
    100%的数据满足P,Q,R≤40,0≤D≤R,且给出的所有的不和谐值不超过1000。 
     
     
    终于AC了
    弱爆了,调一个网络流都调了一上午,各种异常错误应有尽有
    这是一个很巧妙的网络流最小割,每一个竖列都要切一个点,所以最开始我们从上一直连到下面
    但是还有第二个条件,相邻的两个点高度差不能超过D
    先不管它
    我们现在求出了一个最大流,但是不满足第二个条件
    3144:[HNOI2013]切糕 <wbr>- <wbr>BZOJ
    所以我们对于每一个点(x,y,z)都向(x-d,y,z)的相邻的4个点连一条无穷大的边,使这种情况不是最大流
    3144:[HNOI2013]切糕 <wbr>- <wbr>BZOJ
    然后就是套网络流的模板了
     
      1 var
      2     map:array[0..70000,-5..5]of longint;
      3     dis,his,pre:array[0..70000]of longint;
      4     vh:array[0..70000]of longint;
      5     fx:array[-5..5]of longint;
      6     a,b,c,d,flow:longint;
      7 
      8 procedure init;
      9 var
     10     i,j,k:longint;
     11 begin
     12     read(b,c,a,d);
     13     for i:=1 to a do
     14       for j:=1 to b do
     15         for k:=1 to c do
     16           begin
     17             read(map[(i-1)*b*c+(j-1)*c+k,1]);
     18             if i>d then
     19             begin
     20               if k>1 then map[(i-1)*b*c+(j-1)*c+k,2]:=100000000;
     21               if j>1 then map[(i-1)*b*c+(j-1)*c+k,3]:=100000000;
     22               if k<c then map[(i-1)*b*c+(j-1)*c+k,4]:=100000000;
     23               if j<b then map[(i-1)*b*c+(j-1)*c+k,5]:=100000000;
     24             end;
     25           end;
     26     fx[1]:=b*c;
     27     fx[2]:=-d*b*c-1;
     28     fx[3]:=-d*b*c-c;
     29     fx[4]:=-d*b*c+1;
     30     fx[5]:=-d*b*c+c;
     31     for i:=1 to 5 do
     32       fx[-i]:=-fx[i];
     33 end;
     34 
     35 function max(x,y:longint):longint;
     36 begin
     37     if x>y then exit(x);
     38     exit(y);
     39 end;
     40 
     41 procedure work;
     42 var
     43     i,j,aug,min:longint;
     44     flag:boolean;
     45 begin
     46     vh[0]:=a*b*c+2;
     47     i:=0;
     48     aug:=maxlongint;
     49     while dis[0]<=a*b*c+1 do
     50       begin
     51         flag:=false;
     52         his[i]:=aug;
     53         if i=0 then
     54           begin
     55             for j:=1 to b*c do
     56               if dis[0]=dis[j]+1 then
     57               begin
     58                 flag:=true;
     59                 pre[j]:=-1;
     60                 break;
     61               end;
     62             if flag then i:=j;
     63           end
     64         else
     65           for j:=-5 to 5 do
     66             if i+fx[j]>0 then
     67             if (map[i,j]>0)and(dis[i]=dis[i+fx[j]]+1) then
     68             begin
     69               flag:=true;
     70               pre[i+fx[j]]:=-j;
     71               if aug>map[i,j] then aug:=map[i,j];
     72               inc(i,fx[j]);
     73               if i>a*b*c then
     74               begin
     75                 inc(flow,aug);
     76                 while i<>0 do
     77                   begin
     78                     inc(map[i,pre[i]],aug);
     79                     dec(map[max(i+fx[pre[i]],0),-pre[i]],aug);
     80                     inc(i,fx[pre[i]]);
     81                     if i<0 then i:=0;
     82                   end;
     83                 aug:=maxlongint;
     84               end;
     85               break;
     86             end;
     87         if flag then continue;
     88         min:=a*b*c+1;
     89         if i=0 then
     90           begin
     91             for j:=1 to b*c do
     92               if min>dis[j] then min:=dis[j];
     93           end
     94         else
     95           for j:=-5 to 5 do
     96             if i+fx[j]>0 then
     97             if (map[i,j]>0)and(dis[i+fx[j]]<min) then min:=dis[i+fx[j]];
     98         dec(vh[dis[i]]);
     99         if vh[dis[i]]=0 then break;
    100         dis[i]:=min+1;
    101         inc(vh[dis[i]]);
    102         if i<>0 then
    103         begin
    104           inc(i,fx[pre[i]]);
    105           if i<0 then i:=0;
    106           aug:=his[i];
    107         end;
    108       end;
    109     write(flow);
    110 end;
    111 
    112 begin
    113     init;
    114     work;
    115 end.
    View Code
  • 相关阅读:
    Leetcode 811. Subdomain Visit Count
    Leetcode 70. Climbing Stairs
    Leetcode 509. Fibonacci Number
    Leetcode 771. Jewels and Stones
    Leetcode 217. Contains Duplicate
    MYSQL安装第三步报错
    .net 开发WEB程序
    JDK版本问题
    打开ECLIPSE 报failed to load the jni shared library
    ANSI_NULLS SQL语句
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3582396.html
Copyright © 2011-2022 走看看