zoukankan      html  css  js  c++  java
  • Hnoi2013 切糕

    题目描述

    题解:

    这个菜鸡认为很神的一道最小割。

    后来发现是模型之一。

    其实将题意理解为,$(x1,y1)$与$(x2,y2)$相邻,$(x1,y1)$位置上选择了$z1$,那么$(x2,y2)$位置上不能取$z1-d$以下的点。

    代码:

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N = 70000;
    const int inf = 0x3f3f3f3f;
    template<typename T>
    inline void read(T&x)
    {
        T f = 1,c = 0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
        x = f*c;
    }
    int p,q,r,d,v[45][45][45],nam[45][45][45],S,T,tot,hed[N],cnt=-1;
    int dx[]={-1,1,0,0};
    int dy[]={0,0,-1,1};
    struct EG
    {
        int to,nxt;
        ll w;
    }e[4*N];
    void ae(int f,int t,ll w)
    {
        e[++cnt].to = t;
        e[cnt].nxt  = hed[f];
        e[cnt].w    = w;
        hed[f] = cnt;
    }
    void AE(int f,int t,ll w)
    {
        ae(f,t,w);
        ae(t,f,0);
    }
    bool check(int x,int y){return x>=1&&y>=1&&x<=p&&y<=q;}
    int dep[N],cur[N];
    bool vis[N];
    bool bfs()
    {
        memcpy(cur,hed,sizeof(cur));
        memset(dep,0x3f,sizeof(dep));
        queue<int>q;
        q.push(1),vis[1]=1,dep[1]=0;
        while(!q.empty())
        {
            int u = q.front();
            q.pop();
            for(int j=hed[u];~j;j=e[j].nxt)
            {
                int to = e[j].to;
                if(e[j].w&&dep[to]>dep[u]+1)
                {
                    dep[to] = dep[u]+1;
                    if(!vis[to])q.push(to),vis[to]=1;
                }
            }
            vis[u]=0;
        }
        return dep[T]!=inf;
    }
    ll dfs(int u,ll lim)
    {
        if(u==T||!lim)return lim;
        ll fl=0,f;
        for(int j=cur[u];~j;j=e[j].nxt)
        {
            cur[u] = j;
            int to = e[j].to;
            if(dep[to]==dep[u]+1&&(f=dfs(to,min(lim,e[j].w))))
            {
                fl+=f,lim-=f;
                e[j].w-=f,e[j^1].w+=f;
                if(!lim)break;
            }
        }
        return fl;
    }
    ll dinic()
    {
        ll ret = 0;
        while(bfs())
            ret+=dfs(S,inf);
        return ret;
    }
    int main()
    {
        read(p),read(q),read(r),read(d);
        S=1,T=0,tot=1;
        memset(hed,-1,sizeof(hed));
        for(int i=1;i<=r+1;i++)for(int j=1;j<=p;j++)for(int k=1;k<=q;k++)nam[i][j][k]=++tot;
        for(int i=1;i<=r;i++)
            for(int j=1;j<=p;j++)
                for(int k=1;k<=q;k++)
                    read(v[i][j][k]),AE(nam[i][j][k],nam[i+1][j][k],v[i][j][k]);
        for(int i=1;i<=p;i++)
            for(int j=1;j<=q;j++)
            {
                AE(S,nam[1][i][j],inf);
                AE(nam[r+1][i][j],T,inf);
            }
        for(int i=d+1;i<=r;i++)
            for(int j=1;j<=p;j++)
                for(int k=1;k<=q;k++)
                {
                    for(int o=0;o<4;o++)
                        if(check(j+dx[o],k+dy[o]))AE(nam[i][j][k],nam[i-d][j+dx[o]][k+dy[o]],inf);
                }
        printf("%lld
    ",dinic());
        return 0;
    }
  • 相关阅读:
    Leetcode 15 3Sum
    Leetcode 383 Ransom Note
    用i个点组成高度为不超过j的二叉树的数量。
    配对问题 小于10 1.3.5
    字符矩阵的旋转 镜面对称 1.2.2
    字符串统计 连续的某个字符的数量 1.1.4
    USACO twofive 没理解
    1002 All Roads Lead to Rome
    USACO 5.5.1 求矩形并的周长
    USACO 5.5.2 字符串的最小表示法
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10349150.html
Copyright © 2011-2022 走看看