• bzoj 3144 切糕


    题目大意:

    一个立方体,每个点有一个值。

    对于每个纵轴,都要选一个点使得选的点的总和最小且每个点与其所在纵轴相邻的纵轴的点的纵坐标之差的绝对值不能超过$d$

    思路:

    因为每个纵轴都只能选一个,考虑最小割

    每个纵轴从S到T连一条链,对于每个限制:从一个链的点$i$向另一个链的$i-d$点连边,这样表示$x-y geq d$

    这样可以保证每一条从$S ightarrow T$的链都被割且满足条件

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<vector>
     9 #include<map>
    10 #include<set>
    11 #define ll long long
    12 #define db double
    13 #define inf 2139062143
    14 #define MAXN 65000
    15 #define MAXM 290000
    16 #define rep(i,s,t) for(register int i=(s),i##__end=(t);i<=i##__end;++i)
    17 #define dwn(i,s,t) for(register int i=(s),i##__end=(t);i>=i##__end;--i)
    18 #define ren for(register int i=fst[x];i;i=nxt[i])
    19 #define Fill(x,t) memset(x,t,sizeof(x))
    20 #define pls(a,b) (a+b)%MOD
    21 #define mns(a,b) (a-b+MOD)%MOD
    22 #define mul(a,b) (1LL*(a)*(b))%MOD
    23 using namespace std;
    24 inline int read()
    25 {
    26     int x=0,f=1;char ch=getchar();
    27     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    28     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    29     return x*f;
    30 }
    31 int n,m,h,d,v[45][45][45];
    32 const int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
    33 struct Dinic
    34 {
    35     int fst[MAXN],nxt[MAXM<<1],to[MAXM<<1],cnt,val[MAXM<<1];
    36     int vis[MAXN],q[MAXN],l,r,S,T,tot,dis[MAXN],cur[MAXN];
    37     Dinic(){memset(fst,0,sizeof(fst));cnt=1,tot=0;}
    38     void add(int u,int v,int w) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,val[cnt]=w;}
    39     void ins(int u,int v,int w) {add(u,v,w);add(v,u,0);}
    40     int bfs()
    41     {
    42         vis[T]=++tot,dis[T]=0,q[l=r=1]=T;int x;
    43         while(l<=r)
    44         {
    45             x=q[l++],cur[x]=fst[x];ren if(val[i^1]&&vis[to[i]]!=tot)
    46                 dis[to[i]]=dis[x]+1,vis[to[i]]=tot,q[++r]=to[i];
    47         }
    48         return vis[S]==tot;
    49     }
    50     int dfs(int x,int a)
    51     {
    52         if(x==T||!a) return a;int flw=0,f;
    53         for(int& i=cur[x];i&&a;i=nxt[i])
    54             if(val[i]&&dis[to[i]]==dis[x]-1&&(f=dfs(to[i],min(a,val[i]))))
    55                 val[i]-=f,val[i^1]+=f,a-=f,flw+=f;
    56         return flw;
    57     }
    58     int solve(int ss,int tt,int res=0)
    59         {S=ss,T=tt;while(bfs()) res+=dfs(S,inf);return res;}
    60 }D;
    61 int t(int x,int y,int z) {return x*n*m+y*m+z-n*m-m-1;}
    62 int ok(int x,int y) {return x&&y&&x<=n&&y<=m;}
    63 int main()
    64 {
    65     n=read(),m=read(),h=read(),d=read();int ss=n*m*h,tt=ss+1,tx,ty;
    66     rep(i,1,h) rep(j,1,n) rep(k,1,m) v[i][j][k]=read();
    67     rep(j,1,n) rep(k,1,m) rep(i,1,h)
    68         if(i>1) D.ins(t(i-1,j,k),t(i,j,k),v[i][j][k]);else D.ins(ss,t(i,j,k),v[i][j][k]);
    69     rep(j,1,n) rep(k,1,m) rep(o,0,3) if(ok(tx=j+dx[o],ty=k+dy[o]))
    70         rep(i,d+1,h) D.ins(t(i,j,k),t(i-d,tx,ty),inf);
    71     rep(i,1,n) rep(j,1,m) D.ins(t(h,i,j),tt,inf);
    72     printf("%d
    ",D.solve(ss,tt));
    73 }
    View Code
  • 相关阅读:
    ES6新特性
    ng-bind与ng-medol 区别
    验证输入两次密码是否一致angularjs
    最全的node.js安装步骤
    JAVA基础
    localStorage 个人使用总结
    mac中怎么安装python3
    macbook配置homebrew以及安装python3
    python之函数进阶
    mysql数据库入门
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/10729113.html
Copyright © 2020-2023  润新知