其他分享
首页 > 其他分享> > 洛谷P3227 [HNOI2013]切糕

洛谷P3227 [HNOI2013]切糕

作者:互联网

题目大意:

一个立方体,每个点一个点权,要求从每个竖轴上选一个点使得点权之和最小

特殊限制:当在某一条竖轴上选择了点\((x,y,z)\)时,与其相邻的竖轴上选择的点纵坐标绝对值相差不能超过\(d\)

哭哭,不会,颓了吴迪的博客

看见点权和最小先想的是最小费用最大流/总点权-最大流,结果是个硬核最小割……

考虑每条竖轴上的点只能选择一个,把每条竖轴串联

考虑相邻竖轴必须选某段区间内的点,把每个点和相邻竖轴所在区间并联

吴迪牛逼

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;
namespace red{
#define eps (1e-8)
    inline int read()
    {
        int x=0;char ch,f=1;
        for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
        if(ch=='-') f=0,ch=getchar();
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return f?x:-x;
    }
    const int N=50*50*50,inf=0x3f3f3f3f;
    int n,m,h,dis,st,ed;
    int dx[4]={0,-1,0,1},dy[4]={1,0,-1,0};
    int head[N],cur[N],cnt=1;
    struct point
    {
        int nxt,to,val;
        point(){}
        point(const int &nxt,const int &to,const int &val):nxt(nxt),to(to),val(val){}
    }a[N<<3];
    inline void link(int x,int y,int z)
    {
        a[++cnt]=(point){head[x],y,z};head[x]=cnt;
        a[++cnt]=(point){head[y],x,0};head[y]=cnt;
    }
    int d[N];
    queue<int> q;
    inline bool bfs()
    {
        for(int i=1;i<=n*m*h+2;++i) cur[i]=head[i],d[i]=0;
        q.push(st);d[st]=1;
        while(!q.empty())
        {
            int now=q.front();
            q.pop();
            for(int i=head[now];i;i=a[i].nxt)
            {
                int t=a[i].to;
                if(!d[t]&&a[i].val)
                {
                    d[t]=d[now]+1;
                    q.push(t);
                }
            }
        }
        return d[ed];
    }
    inline int dfs(int now,int c)
    {
        if(now==ed||!c) return c;
        int ret=c,f;
        for(int i=cur[now];i;i=a[i].nxt)
        {
            cur[now]=i;
            int t=a[i].to;
            if(d[t]==d[now]+1)
            {
                f=dfs(t,min(a[i].val,ret));
                a[i].val-=f;
                a[i^1].val+=f;
                ret-=f;
                if(!ret) return c;
            }
        }
        if(ret==c) d[now]=0;
        return c-ret;
    }
    inline int dinic()
    {
        int ret=0;
        while(bfs()) ret+=dfs(st,inf);
        return ret;
    }
    inline int pos(int k,int i,int j)
    {
        return (k-1)*(n*m)+(i-1)*m+j;
    }
    inline void main()
    {
        n=read(),m=read(),h=read();
        dis=read();
        st=n*m*h+1,ed=n*m*h+2;
        for(int x,k=1;k<=h;++k)
        {
            for(int i=1;i<=n;++i)
            {
                for(int j=1;j<=m;++j)
                {
                    x=read();
                    if(k==1) link(st,pos(1,i,j),x),link(pos(h,i,j),ed,inf);
                    else link(pos(k-1,i,j),pos(k,i,j),x);
                    for(int t=0;t<4;++t)
                    {
                        int tx=i+dx[t],ty=j+dy[t];
                        if(tx<1||tx>n||ty<1||ty>m) continue;
                        if(k-dis>=1) link(pos(k,i,j),pos(k-dis,tx,ty),inf);
                        if(k+dis<=h) link(pos(k+dis,tx,ty),pos(k,i,j),inf);
                    }
                }
            }
        }
        printf("%d\n",dinic());
    }
}
signed main()
{
    red::main();
return 0;
}

标签:切糕,P3227,int,dis,竖轴上,HNOI2013,ch,include,getchar
来源: https://www.cnblogs.com/knife-rose/p/12100211.html