传送门

两个感受:码量感人……大佬nb……

规则一:$m$条路径都不相交,那么每一个点只能经过一次,那么考虑拆点,把每一个点拆成$A_{i,j}$和$B_{i,j}$,然后两点之间连一条容量$1$,费用该点本身数值的边,表明这个点只能被选一次,然后每一个点的$B$向它能到达的点的$A$连边,表明能从这个点到另一个点,容量随意,费用$0$,然后源点向第一排所有点的$A$连边,最后一排所有点的$B$向汇点连边,都是容量随意,费用$0$,然后跑一个最大费用流即可

规则二:每一个点可以被选多次,那么不用拆点了,直接每一个点向它能到的点连边,容量$1$,表明一条边只能被选一次,费用为该点的数值,源点向第一排所有点连边,容量$1$,费用$0$,最后一排所有点向汇点连边,费用为该点的数值,然后跑一个最大费用流即可

规则三:把每一条边只能选一次的限制去掉,总之就是除了源点到第一排的边,其他边的容量都改为$inf$,然后跑一个最大费用流

 //minamoto
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
const int N=,M=;
int ver[M],head[N],flow[M],edge[M],Next[M],tot=;
int vis[N],dis[N],disf[N],Pre[N],last[N],s=,t=;
int a[][],b[][];
queue<int> q;
inline void add(int u,int v,int f,int e){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot,flow[tot]=f,edge[tot]=e;
ver[++tot]=u,Next[tot]=head[v],head[v]=tot,flow[tot]=,edge[tot]=-e;
}
bool spfa(){
memset(dis,0xef,sizeof(dis));
q.push(s),dis[s]=,disf[s]=inf,Pre[t]=-;
while(!q.empty()){
int u=q.front();q.pop();vis[u]=;
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(flow[i]&&dis[v]<dis[u]+edge[i]){
dis[v]=dis[u]+edge[i],last[v]=i,Pre[v]=u;
disf[v]=min(disf[u],flow[i]);
if(!vis[v]) vis[v]=,q.push(v);
}
}
}
return ~Pre[t];
}
int dinic(){
int maxcost=;
while(spfa()){
int u=t;
maxcost+=disf[t]*dis[t];
while(u!=s){
flow[last[u]]-=disf[t];
flow[last[u]^]+=disf[t];
u=Pre[u];
}
}
return maxcost;
}
void clear(){
tot=,memset(head,,sizeof(head));
}
int main(){
int n,m,k,o,num=;
k=m=read(),n=read();
o=((m<<)+n-)*n>>;
for(int i=;i<=n;++i,++k)
for(int j=;j<=k;++j)
a[i][j]=read(),b[i][j]=++num;
k=m;
for(int i=;i<=k;++i)
add(s,b[][i],,);
for(int i=;i<n;++i,++k)
for(int j=;j<=k;++j){
add(b[i][j],b[i][j]+o,,a[i][j]);
add(b[i][j]+o,b[i+][j],,);
add(b[i][j]+o,b[i+][j+],,);
}
for(int i=;i<=k;++i){
add(b[n][i],b[n][i]+o,,a[n][i]);
add(b[n][i]+o,t,,);
}
printf("%d\n",dinic());
clear();
k=m;
for(int i=;i<=k;++i)
add(s,b[][i],,);
for(int i=;i<n;++i,++k)
for(int j=;j<=k;++j){
add(b[i][j],b[i+][j],,a[i][j]);
add(b[i][j],b[i+][j+],,a[i][j]);
}
for(int i=;i<=k;++i)
add(b[n][i],t,inf,a[n][i]);
printf("%d\n",dinic());
clear();
k=m;
for(int i=;i<=m;++i) add(s,b[][i],,);
for(int i=;i<n;++i,++k)
for(int j=;j<=k;++j){
add(b[i][j],b[i+][j],inf,a[i][j]);
add(b[i][j],b[i+][j+],inf,a[i][j]);
}
for(int i=;i<=k;++i) add(b[n][i],t,inf,a[n][i]);
printf("%d\n",dinic());
return ;
}

洛谷P4013 数字梯形问题(费用流)的更多相关文章

  1. 洛谷P4013 数字梯形问题(费用流)

    题意 $N$行的矩阵,第一行有$M$个元素,第$i$行有$M + i - 1$个元素 问在三个规则下怎么取使得权值最大 Sol 我只会第一问qwq.. 因为有数量的限制,考虑拆点建图,把每个点拆为$a ...

  2. 洛谷 P4013 数字梯形问题【最大费用最大流】

    第一问:因为每个点只能经过一次,所以拆点限制流量,建(i,i',1,val[i]),然后s向第一行建(s,i,1,0),表示每个点只能出发一次,然后最后一行连向汇点(i',t,1,0),跑最大费用最大 ...

  3. 洛谷P4013数字梯形问题——网络流24题

    题目:https://www.luogu.org/problemnew/show/P4013 最大费用最大流裸题: 注意:在第二种情况中,底层所有点连向汇点的边容量应该为inf,因为可以有多条路径结束 ...

  4. 洛谷 P4013 数字梯形问题

    ->题目链接 题解: 网络流. #include<cstdio> #include<iostream> #include<queue> #include< ...

  5. codevs 1913 数字梯形问题 费用流

    题目链接 给你一个数字梯形, 最上面一层m个数字, 然后m+1,......m+n-1个. n是层数. 在每个位置, 可以向左下或右下走.然后让你从最顶端的m个数字开始, 走出m条路径, 使得路过的数 ...

  6. 洛谷 1004 dp或最大费用流

    思路: dp方法: 设dp[i][j][k][l]为两条没有交叉的路径分别走到(i,j)和(k,l)处最大价值. 则转移方程为 dp[i][j][k][l]=max(dp[i-1][j][k-1][l ...

  7. 2018.10.15 loj#6010. 「网络流 24 题」数字梯形(费用流)

    传送门 费用流经典题. 按照题目要求建边. 为了方便我将所有格子拆点,三种情况下容量分别为111,infinfinf,infinfinf,费用都为validi,jval_{id_{i,j}}valid ...

  8. 洛谷P4003 无限之环(费用流)

    传送门 神仙题啊……不看题解我可能一年都不一定做得出来……FlashHu大佬太强啦 到底是得有怎样的脑回路才能一眼看去就是费用流啊…… 建好图之后套个板子就好了,那么我们着重来讨论一下怎么建图 首先, ...

  9. 洛谷P4012 深海机器人问题(费用流)

    题目描述 深海资源考察探险队的潜艇将到达深海的海底进行科学考察. 潜艇内有多个深海机器人.潜艇到达深海海底后,深海机器人将离开潜艇向预定目标移动. 深海机器人在移动中还必须沿途采集海底生物标本.沿途生 ...

随机推荐

  1. Deep Learning 学习笔记(6):神经网络( Neural Network )

    神经元: 在神经网络的模型中,神经元可以表示如下 神经元的左边是其输入,包括变量x1.x2.x3与常数项1, 右边是神经元的输出 神经元的输出函数被称为激活函数(activation function ...

  2. Word2Vec之Skip-Gram模型

    理解 Word2Vec 之 Skip-Gram 模型 模型 Word2Vec模型中,主要有Skip-Gram和CBOW两种模型,从直观上理解,Skip-Gram是给定input word来预测上下文. ...

  3. 十分钟学会Fiddler

    一.Fiddler介绍 Fiddler是一个http抓包改包工具,fiddle英文中有“欺骗.伪造”之意,与wireshark相比它更轻量级,上手简单,因为只能抓http和https数据包,所以在针对 ...

  4. log4j配置文件的手动加载与配置初始化

    一. 本地项目: 初始化log4j的日志配置,指定到src目录下(建议用2)         //1. 本地项目-属性文件配置         PropertyConfigurator.configu ...

  5. Java基础知识(二)之控制语句

    1.条件运算符   ⑴if...else... ⑵三目表达式——X?Y:Z 当X为真时,结果为Y:反之,为Z. ⑶switch(表达式){ case 1:    执行代码块 1; break: cas ...

  6. 【NOIP2008】传纸条

    [描述] Description 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就 ...

  7. mongo 修改器 $inc/$set/$unset/$pop/$push/$pull/$addToSet

    mongo $inc 可以对集合里面的某些值是数字的增减.看代码 $set  可以进行修改,并且不存在的时候默认添加. 同时还能该变数据的类型. 还可以该变内嵌元素的值 用.调用 $unset  删除 ...

  8. php格式化时间戳显示友好的时间

    在项目中时间一律显示为2014-10-20 10:22显得很呆板.在微博.QQ空间等网站通常会显示为几秒前,几分钟前,几小时前等容易阅读的时间,我们称之为友好的时间格式.那么用php怎么实现呢? 大体 ...

  9. Glade编程

    一.简介 如果有一种软件能将图形界面的设计及时地展现于开发人员的面前,而且在设计完后能直接看到界面的外观效果,这样就使程序员的主要精力集中于应用程序核心功能的开发上,这就是所谓的可视化编程思想.   ...

  10. 用CSS3.0画圆

    CSS3.0中有一个border-radius属性,这个属性允许向 div 元素添加圆角边框,也就是div边角不再一直是直角,在CSS3.0中可以做成圆角了,所以我们可以用这个属性用div画一个圆,或 ...