zoukankan      html  css  js  c++  java
  • 【bzoj3144】[Hnoi2013]切糕 最小割

    [Hnoi2013]切糕

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 2228  Solved: 1220
    [Submit][Status][Discuss]

    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

    题解:

      题意表示看不懂了,语文水平差,没办法。

      切割就是每条竖线上选择一个点来断开,

      如果没有这个限制是什么,就是直接一层中的点向下一层对应的点连边

      那么限制的话就是当前的点割了不能割

      那么就是也可以转换为,割了这条边,与其相距d的边割了无效

      发现一个点向上向下都制约D和每个点都只向下制约是等价的

      所以从该点向下d连一条无穷的边,不能割

    当时看这个人才会的

      1 #include<cmath>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 
      7 #define rad 100000000
      8 #define inf 1000000000
      9 #define ll long long 
     10 #define eps 1e-10
     11 #define pa pair<ll,int>
     12 using namespace std;
     13 ll read()
     14 {
     15     ll x=0,f=1;char ch=getchar();
     16     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     17     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     18     return x*f;
     19 }
     20 
     21 int xx[4]={0,0,1,-1},yy[4]={1,-1,0,0};
     22 int P,Q,r,d,T,cnt=1;
     23 int f[45][45][45];
     24 int cur[100005],last[100005],h[100005],q[100005];
     25 
     26 struct edge{
     27     int to,next,v;
     28 }e[1000005];
     29 int p(int x,int y,int z)
     30 {
     31     if(z==0)return 0;
     32     return (z-1)*P*Q+(x-1)*Q+y;
     33 }
     34 void insert(int u,int v,int w)
     35 {
     36     e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt;e[cnt].v=w;
     37     e[++cnt].to=u;e[cnt].next=last[v];last[v]=cnt;e[cnt].v=0;
     38 }
     39 void build()
     40 {
     41     for(int i=1;i<=P;i++)
     42         for(int j=1;j<=Q;j++)
     43         {
     44             for(int k=1;k<=r;k++)
     45             {
     46                 insert(p(i,j,k-1),p(i,j,k),f[i][j][k]);
     47                 if(k>d)
     48                 for(int dir=0;dir<4;dir++)
     49                 {
     50                     int nx=i+xx[dir],ny=j+yy[dir];
     51                     if(nx<1||ny<1||nx>P||ny>Q)continue;
     52                     insert(p(i,j,k),p(nx,ny,k-d),inf);
     53                 }
     54             }
     55             insert(p(i,j,r),T,inf);
     56         }
     57 }
     58 bool bfs()
     59 {
     60     int head=0,tail=1;
     61     memset(h,-1,sizeof(h));
     62     q[0]=0;h[0]=0;
     63     while(head!=tail)
     64     {
     65         int now=q[head];head++;
     66         for(int i=last[now];i;i=e[i].next)
     67             if(h[e[i].to]==-1&&e[i].v)
     68             {
     69                 h[e[i].to]=h[now]+1;
     70                 q[tail++]=e[i].to;
     71             }
     72     }
     73     return h[T]!=-1;
     74 }
     75 int dfs(int x,int f)
     76 {
     77     if(x==T)return f;
     78     int w,used=0;
     79     for(int i=cur[x];i;i=e[i].next)
     80         if(h[x]+1==h[e[i].to])
     81         {
     82             w=dfs(e[i].to,min(f-used,e[i].v));
     83             used+=w;e[i].v-=w;e[i^1].v+=w;
     84             if(e[i].v)cur[x]=i;
     85             if(used==f)return f;
     86         }
     87     if(!used)h[x]=-1;
     88     return used;
     89 }
     90 int dinic()
     91 {
     92     int tmp=0;
     93     while(bfs())
     94     {
     95         for(int i=0;i<=T;i++)cur[i]=last[i];
     96         tmp+=dfs(0,inf);
     97     }
     98     return tmp;
     99 }
    100 int main()
    101 {
    102     P=read();Q=read();r=read();T=P*Q*r+1;
    103     d=read();
    104     for(int i=1;i<=r;i++)
    105         for(int j=1;j<=P;j++)
    106             for(int k=1;k<=Q;k++)
    107                 f[j][k][i]=read();
    108     build();
    109     printf("%d
    ",dinic());
    110 }
  • 相关阅读:
    【结对编程收获】
    【第二次个人作业】结对作业Core第一组:四则运算生成PB16061082+PB16120517
    【第七周读书笔记】读《计算机系统详解》
    【第五周课堂作业】创新案例分析
    【第六周读书笔记】计算机体系结构读后感
    个人总结——马睿淳
    团队项目心得(6.15)
    团队项目心得
    《代码大全》读书笔记——第九周
    《我是一只IT小小鸟》(续)读书笔记——第八周
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8277395.html
Copyright © 2011-2022 走看看