zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    CF809D Hitchhiking in the Baltic States
    CF1188D Make Equal
    CF1137 Train Car Selection
    LOJ3215「PA 2019」Muzyka pop
    洛谷4455 [CQOI2018]社交网络 (有向图矩阵树定理)(学习笔记)
    洛谷3571 POI2014 SUP-Supercomputer (斜率优化)
    洛谷2805 [NOI2009]植物大战僵尸 (拓扑排序+最小割)
    洛谷2120 [ZJOI2007]仓库建设(斜率优化dp)
    洛谷2494 [SDOI2011]保密 (分数规划+最小割)
    洛谷3648 [APIO2014]序列分割(斜率优化+dp)
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/10729113.html
Copyright © 2011-2022 走看看