• BZOJ3144: [Hnoi2013]切糕


    题解;

    WJMZBMR:

    考虑网络流,
    我们构造一个P*Q*(R+1)的点阵,用(i,j,k)表示一个点
    那么(i,j,k) -> (i,j,k+1) 的流量为原图中(i,j,k)的不和谐值。
    S向所有底层连无穷边,所有顶层向T连无穷边。
    那么(i,j,k) -> (i,j,k+1)被割表示f(i,j)=k。。。
    同时我们让(i,j,k) -> (i',j',k-D)连一条无穷边,就能保证相邻两个不超过D了。
    (i,j)与(i',j')相邻。

    意思是什么呢?

    首先每个点向下连容量为其权值的边,意思是这一竖线只能选一个,之前的划在s割,之后的在t割。

    然后我们连边 (i,j,k)到(i',j',k-d)意思就是 这两个点必须同割!不同割会发生什么情况

    (i‘,j’)在k-d高度以前就选了,而(i,j)在k还没选。或者返回来,高度超过了D所以不合法。

    这样就保证了合法性。

    代码:

      1 #include<cstdio>
      2 
      3 #include<cstdlib>
      4 
      5 #include<cmath>
      6 
      7 #include<cstring>
      8 
      9 #include<algorithm>
     10 
     11 #include<iostream>
     12 
     13 #include<vector>
     14 
     15 #include<map>
     16 
     17 #include<set>
     18 
     19 #include<queue>
     20 
     21 #include<string>
     22 
     23 #define inf 1000000000
     24 
     25 #define maxn 50*50*50
     26 
     27 #define maxm 20*50*50*50
     28 
     29 #define eps 1e-10
     30 
     31 #define ll long long
     32 
     33 #define pa pair<int,int>
     34 
     35 #define for0(i,n) for(int i=0;i<=(n);i++)
     36 
     37 #define for1(i,n) for(int i=1;i<=(n);i++)
     38 
     39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
     40 
     41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
     42 
     43 #define for4(i,x) for(int i=head[x],y;i;i=e[i].next)
     44 
     45 #define mod 1000000007
     46 
     47 using namespace std;
     48 
     49 inline int read()
     50 
     51 {
     52 
     53     int x=0,f=1;char ch=getchar();
     54 
     55     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     56 
     57     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
     58 
     59     return x*f;
     60 
     61 }
     62 int  D,H,n,m,s,t,maxflow,tot,head[maxn],cur[maxn],h[maxn],num[50][50][50];
     63 queue<int>q;
     64 struct edge{int go,next,v;}e[maxm];
     65 inline void add(int x,int y,int v)
     66 {
     67     e[++tot]=(edge){y,head[x],v};head[x]=tot;
     68     e[++tot]=(edge){x,head[y],0};head[y]=tot;
     69 }
     70 bool bfs()
     71 {
     72     for(int i=s;i<=t;i++)h[i]=-1;
     73     q.push(s);h[s]=0;
     74     while(!q.empty())
     75     {
     76         int x=q.front();q.pop();
     77         for(int i=head[x];i;i=e[i].next)
     78          if(e[i].v&&h[e[i].go]==-1)
     79          {
     80             h[e[i].go]=h[x]+1;q.push(e[i].go);
     81          }
     82     }
     83     return h[t]!=-1;
     84 }
     85 int dfs(int x,int f)
     86 {
     87     if(x==t) return f;
     88     int tmp,used=0;
     89     for(int i=cur[x];i;i=e[i].next)
     90      if(e[i].v&&h[e[i].go]==h[x]+1)
     91     {
     92         tmp=dfs(e[i].go,min(e[i].v,f-used));
     93         e[i].v-=tmp;if(e[i].v)cur[x]=i;
     94         e[i^1].v+=tmp;used+=tmp;
     95         if(used==f)return f;       
     96     }
     97     if(!used) h[x]=-1;
     98     return used;
     99 }
    100 void dinic()
    101 {
    102     maxflow=0;
    103     while(bfs())
    104     {
    105         for (int i=s;i<=t;i++)cur[i]=head[i];maxflow+=dfs(s,inf);
    106     }
    107 }
    108 const int dx[4]={0,0,1,-1};
    109 const int dy[4]={1,-1,0,0};
    110 
    111 int main()
    112 
    113 {
    114 
    115     freopen("input.txt","r",stdin);
    116 
    117     freopen("output.txt","w",stdout);  
    118     n=read();m=read();H=read();D=read();
    119     for1(k,H+1)for1(i,n)for1(j,m)num[i][j][k]=++tot;
    120     s=0;t=tot+1;
    121     tot=1;
    122     for1(k,H)for1(i,n)for1(j,m)add(num[i][j][k],num[i][j][k+1],read());
    123     for1(i,n)for1(j,m)add(s,num[i][j][1],inf),add(num[i][j][H+1],t,inf);
    124     for1(k,H)for1(i,n)for1(j,m)for0(l,3)
    125     {
    126         int x=i+dx[l],y=j+dy[l];
    127         if(x<1||x>n||y<1||y>m)continue;
    128         //if(k+D<H+2)add(num[i][j][k],num[x][y][k+D],inf);
    129         if(k-D>0)add(num[i][j][k],num[x][y][k-D],inf);
    130     }
    131     dinic();
    132     cout<<maxflow<<endl;
    133 
    134     return 0;
    135 
    136 }  
    View Code
  • 相关阅读:
    小程序本地数据的存储
    cocos2d-x中CCTableView介绍
    C++中map容器的说明和使用技巧
    不修改代码,关闭vs2010 C4819警告
    Cocos2d-x 处理双击事件的两种方法
    Cocos2d-x 实现模态对话框
    Cocos2d-x init() 和 onEnter() 区别
    Cocos2d-x 中 CCProgressTimer
    Cocos2d-x 实现技能冷却效果
    输出第 n 个斐波纳契数(Fibonacci)
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4182855.html
Copyright © 2020-2023  润新知