传送门

两个感受:码量感人……大佬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. java成神之——properties,lambda表达式,序列化

    Properties 加载defaults.properties文件 写Properties到xml文件 读Properties从xml文件 Lambda表达式 自定义 内置 sort方法中使用Lam ...

  2. 浅析bootstrap原理及优缺点

    网格系统的实现原理,是通过定义容器大小,平分12份(也有平分成24份或32份,但12份是最常见的),再调整内外边距,最后结合媒体查询,就制作出了强大的响应式网格系统   网格系统的实现原理,是通过定义 ...

  3. leetcode872

    class Solution { public: vector<int> v1; vector<int> v2; void GetLeaf(TreeNode* tree, in ...

  4. Neo4j的集群架构

    Neo4j的集群架构 参考资料: 1.http://lib.csdn.net/article/mysql/5742,其中有集群的集中模式master-slave.sharding.多主模式.cassa ...

  5. tomcat 7 7.0.73 url 参数 大括号 {} 不支持 , 7.0.67支持

    7.0.73 url有JSON.stringify一个对象,然后作为参数拼接.结果请求报400错误,但是tomcat 7.0.67版本没有问题,猜测是高级版本对url参数比较严格.  处理方法:   ...

  6. 第01章 开发准备(对最新版的RN进行了升级)1-2+项目技术分解

  7. Linux问题:开启网关

    1 开启网关 1.1 问题描述 虚拟机每次重启后,都需要利用 ifup eth0 来手动开启网关,否则获取到的IP地址为回环127.0.0.1 1.2 解决办法 修改ifcfg-eth0中 ONBOO ...

  8. Android NDK打印log到logcat的方法

    头文件 : <android/log.h> 函数: __android_log_print(ANDROID_LOG_XXX,LOG_TAG,content) 第一个参数是Log级别,比如: ...

  9. CF 961G Partitions

    推不动式子 我们考虑每一个$w_i$对答案的贡献,因为题目中定义集合的价值为$W(S) = \left | S \right |\sum_{x \in S}w_x$,这个系数$\left | S \r ...

  10. 使用rpmbuild打包时不对文件进行strip操作

    使用rpmbuild打包时不对文件进行strip操作 摘自: https://www.ichenfu.com/2017/11/20/rpmbuild-not-strip/ By Chen Fu 发表于 ...