BZOJ3144/LG3227 「HNOI2013」切糕 最小割离散变量模型

问题描述

BZOJ3144

LG3227

还想粘下样例

输入:

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

输出:

6

题解

关于离散变量模型,我不想再抄一遍,所以:

对于样例,可以建立出这样的图

这是一个最小割模型,哪条边满流就代表在这个位置选择了哪个值。

网络流的主要思想就是通过点互化,将限制条件在边上体现出来。

所以比 \([1,r]\) 要再多建立一个点,但是最后增加的一层不能建立横向边


\(\mathrm{Code}\)

#include<bits/stdc++.h>
using namespace std;

const int maxn=42;
const int INF=0x3f3f3f3f;

int p,q,r,D;
int v[maxn][maxn][maxn];

int Head[maxn*maxn*maxn*2],Next[maxn*maxn*maxn*10],to[maxn*maxn*maxn*10],w[maxn*maxn*maxn*10],tot=1;

int S,T;
void add(int x,int y,int z){
//  if(x==4&&y==S) puts("Warning!");
//  if(x==S&&y==4) puts("Warning!");
    to[++tot]=y,Next[tot]=Head[x],Head[x]=tot,w[tot]=z;
}

int id(int x,int y,int z){
    return (z-1)*p*q+(x-1)*q+y;
}

void Init(void){
    scanf("%d%d%d%d",&p,&q,&r,&D);
    for(int i=1;i<=r;i++){
        for(int j=1;j<=p;j++){
            for(int k=1;k<=q;k++){
                scanf("%d",&v[j][k][i]);
            }
        }
    }
}

int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};

bool check(int x,int y,int z){
    return ((x>=1&&x<=p)&&(y>=1&&y<=q)&&(z>=1&&z<=r));
}


void Graph_build(void){
    S=p*q*(r+1)+2,T=S+1;
    for(int i=1;i<=p;i++){
        for(int j=1;j<=q;j++){
            add(S,id(i,j,1),INF);add(id(i,j,1),S,0);
            for(int k=1;k<=r;k++){
                add(id(i,j,k),id(i,j,k+1),v[i][j][k]);
                add(id(i,j,k+1),id(i,j,k),0);
//              add(id(i,j,k),id(i,j,k-1),v[i][j][k-1]);
//              add(id(i,j,k-1),id(i,j,k),0);
            }
            add(id(i,j,r+1),T,INF);add(T,id(i,j,r+1),0);
        }
    }
    for(int i=1;i<=p;i++){
        for(int j=1;j<=q;j++){
            for(int e=0;e<4;e++){
                int mx=i+dx[e],my=j+dy[e];
                if(mx<1||mx>p||my<1||my>q) continue;
                for(int h=D+1;h<=r;h++){
                    add(id(i,j,h),id(mx,my,h-D),INF);
                    add(id(mx,my,h-D),id(i,j,h),0);
                }
            }
        }
    }
}

int ans;
int d[maxn];

bool bfs(void){
    memset(d,0,sizeof(d));
    queue<int>q;q.push(S);d[S]=1;
    while(q.size()){
        int x=q.front();q.pop();
        for(int i=Head[x];i;i=Next[i]){
            int y=to[i];
            if(d[y]||!w[i]) continue;
            d[y]=d[x]+1;q.push(y);
            if(y==T) return true;
        }
    }
    return false;
}

int dfs(int x,int flow){
    if(x==T) return flow;
    int rest=flow;
    for(int i=Head[x];i&&rest;i=Next[i]){
        int y=to[i];
        if(d[y]!=d[x]+1||!w[i]) continue;
        int k=dfs(y,min(rest,w[i]));
        if(!k) d[y]=0;
        else w[i]-=k,w[i^1]+=k,rest-=k;
    }
    return flow-rest;
}

void Dinic(void){
    int t;
    while(bfs()){
        while(t=dfs(S,INF)) ans+=t; 
    }
}

void Dbug(){
    for(int i=2;i<=tot;i+=2){
        printf("%d %d %d\n",to[i^1],to[i],w[i]);
    }
}

//#define debug

void Work(void){
    Graph_build();
    
    
    #ifdef debug
        Dbug();
        printf("S:%d T:%d\n",S,T);
    #endif
    Dinic();
    printf("%d\n",ans);
}

int main(){
    Init();
    Work();
    return 0;
}
全部评论

相关推荐

2025-11-23 15:33
已编辑
门头沟学院 Java
CUTMR:换账号试试重启推荐算法,我换账号之后回复率还不错,约莫有个20%左右的消息回复率,前几页、主动招呼的HR也开始符合我期望薪资,此前的大号从招呼、回复、前几页的岗位薪资在涨幅30%+以上 用着用着聊着聊着就变成-20%,而且我开通会员之后直接0面试
点赞 评论 收藏
分享
作为带过好几个实习生的老mentor,我见过有同学带着一腔热血来实习,最后却只带走一份单薄的履历。实习,是你从学校到职场最关键的过渡期,它的价值远不止一份实习证明。今天,我不讲大道理,就从我作为Mentor的视角,给你们几条能立刻用上的建议。记住,你的目标不是当个好学生,而是成为一个值得信赖的职场新人。一、&nbsp;心态转变:从被动答题到主动解题这是我最想强调的一点。学生思维是:等待老师布置明确的作业,然后完成它。职场思维是:主动发现模糊的问题,然后解决它。反面事例:接到任务后,埋头就做,遇到困难不吭声,直到截止日期才说“这个我不会”。Mentor期待的是啥呢?首先是确认目标:接到任务后,先用自己的话复述一遍:“我理解这个任务是要达成XX效果,对吗?”&nbsp;确保方向没错。然后是主动思考:不要只带问题来,要带“选择题”。问“这个数据我不会查,我尝试了A和B方法都失败了,您看是方法C更合适,还是我有其他没考虑到的渠道?”&nbsp;这证明了你的思考和努力。最后是闭环思维:任务完成后,主动告知结果:“XX任务已完成,数据/文件已发您邮箱,并同步在团队网盘了。其中有个小发现是……,供您参考。”&nbsp;让一切有始有终。二、&nbsp;沟通方式:实习生的很多错误,都源于“想当然”和“不敢问”。反面教材:在做一个PPT时,因为不确定公司模板,就套用了自己觉得好看的模板,结果不能用。那么怎么确认,怎么提问呢?第一个,不懂就问,但别重复问:第一次问,是学习;同样的问题问第三次,就是不用心。准备一个笔记本,把关键信息、操作流程、注意事项都记下来。第二个,及时汇报,别等追问:特别是遇到卡壳或可能延期时,一定要提前说。Mentor不怕你慢,就怕你失联。没事儿更新一下进度:目前已完成80%,但在XX环节遇到点阻力,正在想办法沟通等回复,预计今天下班前确定结果,到时候给您,这样说能让人极度安心。第三个,珍惜1on1机会:和Mentor的定期沟通,不是你被动接受批评,而是你主动获取信息和反馈的黄金时间。提前准备好:a)&nbsp;本周工作进展;b)&nbsp;遇到的困惑/挑战;c)&nbsp;希望学习的新技能;d)&nbsp;对团队业务的任何好奇。三、&nbsp;工作习惯:&nbsp;专业性体现在细节里职业素养不是空话,它藏在每一个你容易忽略的细节中。1.&nbsp;邮件/沟通软件礼仪:邮件:标题清晰(如【实习生XX-XX项目周报】),正文称呼得体,结尾有落款。别用“在吗?”开头。工作群:别发表情包刷屏,沟通事情简明扼要。收到任务或通知,回复“收到,谢谢”,这是基本的确认和尊重。2.&nbsp;文件管理与命名:我会观察实习生的桌面,看他们的使用习惯,乱糟糟的桌面说明他没条理。文件命名要使用统一的命名规则:日期_项目名_内容_版本_姓名。例如:20231027_秋招海报_初版_张三。这能为整个团队节省大量沟通成本。3.&nbsp;对待杂活的态度:复印、整理数据、会议纪要……这些dirty&nbsp;work是不可避免的。但优秀的人是能从中找到价值的:整理数据时,可以留意数据之间的关联或异常,做会议纪要时,可以梳理出会议的决策和待办事项。四、&nbsp;终极目标:带走三样东西1.&nbsp;一段能讲出STAR法则的实战经历:这直接决定了你未来求职简历的厚度。2.&nbsp;一位可以为你未来背书的Mentor/同事:好好表现,离职时保持联系,他们可能成为你未来求职的推荐人和内推渠道。3.&nbsp;对行业和岗位的真实认知:通过这次实习,你想清楚自己是更热爱这个行业,还是想赶紧跑路?这个答案,价值千金。最后,作为你们的Mentor,我想说:大胆去试,勇敢去问,别怕犯错。实习期是你犯错成本最低的时候。展现出你的靠谱、主动和思考,我们做Mentor的,会非常乐意把更核心的任务交给你,因为带你,也是在为团队培养未来的战友。希望这些建议能帮你少走弯路,打一场漂亮的实习战!
家族企业:实习一年比在大学多年都有用
第一次找实习,我建议__
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务