BZOJ_3144_[Hnoi2013]切糕_最小割

Description

Input

第一行是三个正整数P,Q,R,表示切糕的长P、 宽Q、高R。第二行有一个非负整数D,表示光滑性要求。接下来是R个P行Q列的矩阵,第z个 矩阵的第x行第y列是v(x,y,z) (1≤x≤P, 1≤y≤Q, 1≤z≤R)。
100%的数据满足P,Q,R≤40,0≤D≤R,且给出的所有的不和谐值不超过1000。

Output

仅包含一个整数,表示在合法基础上最小的总不和谐值。

Sample Input

2 2 2
1
6 1
6 1
2 6
2 6

Sample Output

6

HINT

最佳切面的f为f(1,1)=f(2,1)=2,f(1,2)=f(2,2)=1



如果没有相邻两个高度不能超过d这个限制,我们直接把这p*q*r个点拿出来求最小割即可。

S->高度为1的(v[1]) 高度为i的->高度为i+1的(v[i+1]) 高度为r的->T(inf)

现在有了限制,即我们不能割掉两个相邻的并且高度差大于d的边。

这样处理:高度为k的点向四周高度为k+d的连一条inf的边,这样我如果割两个高度差大于d的边,就还会有一条inf的通路,使得S,T连通。

限制了不能割这样的两条边。

代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 3050
#define M 300050
#define S (n*m+1)
#define T (n*m+2)
#define inf 100000000
#define p(i,j) ((i-1)*m+j)
int head[N],to[M],nxt[M],flow[M],cnt=1,n,m,dep[N],Q[N],l,r;
inline void add(int u,int v,int f) {
    to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; flow[cnt]=f;
    to[++cnt]=u; nxt[cnt]=head[v]; head[v]=cnt; flow[cnt]=0;
}
bool bfs() {
    memset(dep,0,sizeof(dep));
    dep[S]=1; l=r=0; Q[r++]=S;
    while(l<r) {
        int x=Q[l++],i;
        for(i=head[x];i;i=nxt[i]) {
            if(!dep[to[i]]&&flow[i]) {
                dep[to[i]]=dep[x]+1;
                if(to[i]==T) return 1;
                Q[r++]=to[i];
            }
        }
    }
    return 0;
}
int dfs(int x,int mf) {
    if(x==T) return mf;
    int nf=0,i;
    for(i=head[x];i;i=nxt[i]) {
        if(dep[to[i]]==dep[x]+1&&flow[i]) {
            int tmp=dfs(to[i],min(mf-nf,flow[i]));
            if(!tmp) dep[to[i]]=0;
            nf+=tmp;
            flow[i]-=tmp;
            flow[i^1]+=tmp;
            if(nf==mf) break;
        }
    }
    return nf;
}
void dinic() {
    int ans=0,f;
    while(bfs()) while(f=dfs(S,inf)) ans+=f;
    printf("%d\n",ans);
}
char s[60];
int main() {
    int A,B,i,j;
    scanf("%d%d%d%d",&n,&m,&A,&B);
    for(i=1;i<=n;i++) {
        scanf("%s",s+1);
        for(j=1;j<=m;j++) {
            if(s[j]==‘#‘) {
                add(S,p(i,j),B);
            }else {
                add(p(i,j),T,B);
            }
        }
    }
    for(i=1;i<=n;i++) {
        for(j=1;j<=m;j++) {
            if(i>1) add(p(i,j),p(i-1,j),A);
            if(i<n) add(p(i,j),p(i+1,j),A);
            if(j>1) add(p(i,j),p(i,j-1),A);
            if(j<m) add(p(i,j),p(i,j+1),A);
        }
    }
    dinic();
}

原文地址:https://www.cnblogs.com/suika/p/8967354.html

时间: 2024-11-03 12:41:57

BZOJ_3144_[Hnoi2013]切糕_最小割的相关文章

【BZOJ 3144】 3144: [Hnoi2013]切糕 (最小割模型)

3144: [Hnoi2013]切糕 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1764  Solved: 965 Description Input 第一行是三个正整数P,Q,R,表示切糕的长P. 宽Q.高R.第二行有一个非负整数D,表示光滑性要求.接下来是R个P行Q列的矩阵,第z个 矩阵的第x行第y列是v(x,y,z) (1≤x≤P, 1≤y≤Q, 1≤z≤R). 100%的数据满足P,Q,R≤40,0≤D≤R,且给出的所有的不和谐值不超

【bzoj3144】[Hnoi2013]切糕 网络流最小割

题目描述 输入 第一行是三个正整数P,Q,R,表示切糕的长P. 宽Q.高R.第二行有一个非负整数D,表示光滑性要求.接下来是R个P行Q列的矩阵,第z个 矩阵的第x行第y列是v(x,y,z) (1≤x≤P, 1≤y≤Q, 1≤z≤R). 100%的数据满足P,Q,R≤40,0≤D≤R,且给出的所有的不和谐值不超过1000. 输出 仅包含一个整数,表示在合法基础上最小的总不和谐值. 样例输入 2 2 2 1 6 1 6 1 2 6 2 6 样例输出 6 题目大意 给定一个p行q列的矩阵,每个位置可以

[BZOJ 3144] [Hnoi2013] 切糕 【最小割】

题目链接:BZOJ - 3144 题目分析 题意:在 P * Q 的方格上填数字,可以填 [1, R] . 在 (x, y) 上填 z 会有 V[x][y][z] 的代价.限制:相邻两个格子填的数字的差的绝对值不能超过 D . 求一个合法的最小总代价. 这道题是一个最小割模型,直接说建图吧. 建图:每个点 (x, y) 拆成 R 个点,(x, y, z) 代表 (x, y) 填 z. 然后从 S 向 (*, *, 1) 连 INF ,从 (*, *, R) 向 T 连 INF . 然后对于 (i

【BZOJ 3144】 [Hnoi2013]切糕 真&#183;最小割

一开始一脸懵逼后来发现,他不就是割吗,我们只要满足条件就割就行了,于是我们把他连了P*Q*R条边,然而我们要怎样限制D呢?我们只要满足对于任意相邻的两条路,只要其有个口大于D就不行就好了因此我们只要把每个点向离他D距离的下面的店连一条Inf连线就可以啦,因此我们就满足了一定是所有相邻的路径上存在不超过距离D的缺口,由于满足这条性质因此至少存在一层两两之间距离不超过D的膜因此最终答案一定是每条路上割一个,因此就让他跑去把! #include <cstdio> #include <cstri

POJ 3469-Dual Core CPU(网络流_最小割求容量)

PS:最小割第一发,我怎么感觉就是求最大流呢,sad.这是求最小割的容量的问题,根据最大流最小割定理,可以转换成求解网络流的最大流流量.这个事==最大流的. Dual Core CPU Time Limit: 15000MS   Memory Limit: 131072K Total Submissions: 19724   Accepted: 8562 Case Time Limit: 5000MS Description As more and more computers are equi

BZOJ_2039_[2009国家集训队]employ人员雇佣_ 最小割

Description 作为一个富有经营头脑的富翁,小L决定从本国最优秀的经理中雇佣一些来经营自己的公司.这些经理相互之间合作有一个贡献指数,(我们用Ei,j表示i经理对j经理的了解程度),即当经理i和经理j同时被雇佣时,经理i会对经理j做出贡献,使得所赚得的利润增加Ei,j.当然,雇佣每一个经理都需要花费一定的金钱Ai,对于一些经理可能他做出的贡献不值得他的花费,那么作为一个聪明的人,小L当然不会雇佣他. 然而,那些没有被雇佣的人会被竞争对手所雇佣,这个时候那些人会对你雇佣的经理的工作造成影响

[bzoj1324]Exca王者之剑_最小割

Exca王者之剑 bzoj-1324 题目大意:题目链接. 注释:略. 想法: 最小割经典模型. 所有格子向源点连权值为格子权值的边. 将棋盘黑白染色后白点反转源汇. 如果两个格子相邻那么黑点向白点连$inf$的有向边. 求最小割即可. 开始把所有点的权值都加上,如果被割掉那么就表示这个格子不选. Code: #include <bits/stdc++.h> #define inf 0x3f3f3f3f #define N 100010 using namespace std; queue&l

[bzoj2229][Zjoi2011]最小割_网络流_最小割树

最小割 bzoj-2229 Zjoi-2011 题目大意:题目链接. 注释:略. 想法: 在这里给出最小割树的定义. 最小割树啊,就是这样一棵树.一个图的最小割树满足这棵树上任意两点之间的最小值就是原图中这两点之间的最小割. 这个性质显然是非常优秀的. 我们不妨这样假设,我么已经把最小割树求出来了,那么这个题就迎刃而解了. 我们可以直接枚举点对,然后暴力验证就可以直接枚举出所有的合法点对是吧. 那么问题来了,我们如何才能求出所有的合法的点对? 这就需要用到了最小割树的构建过程. 我们最小割树的构

HDU 3046-Pleasant sheep and big big wolf(网络流_最小割)

Pleasant sheep and big big wolf Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2254    Accepted Submission(s): 946 Problem Description In ZJNU, there is a well-known prairie. And it attracts p