洛谷P4013 数字梯形问题(费用流)
两个感受:码量感人……大佬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 数字梯形问题(费用流)的更多相关文章
- 洛谷P4013 数字梯形问题(费用流)
题意 $N$行的矩阵,第一行有$M$个元素,第$i$行有$M + i - 1$个元素 问在三个规则下怎么取使得权值最大 Sol 我只会第一问qwq.. 因为有数量的限制,考虑拆点建图,把每个点拆为$a ...
- 洛谷 P4013 数字梯形问题【最大费用最大流】
第一问:因为每个点只能经过一次,所以拆点限制流量,建(i,i',1,val[i]),然后s向第一行建(s,i,1,0),表示每个点只能出发一次,然后最后一行连向汇点(i',t,1,0),跑最大费用最大 ...
- 洛谷P4013数字梯形问题——网络流24题
题目:https://www.luogu.org/problemnew/show/P4013 最大费用最大流裸题: 注意:在第二种情况中,底层所有点连向汇点的边容量应该为inf,因为可以有多条路径结束 ...
- 洛谷 P4013 数字梯形问题
->题目链接 题解: 网络流. #include<cstdio> #include<iostream> #include<queue> #include< ...
- codevs 1913 数字梯形问题 费用流
题目链接 给你一个数字梯形, 最上面一层m个数字, 然后m+1,......m+n-1个. n是层数. 在每个位置, 可以向左下或右下走.然后让你从最顶端的m个数字开始, 走出m条路径, 使得路过的数 ...
- 洛谷 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 ...
- 2018.10.15 loj#6010. 「网络流 24 题」数字梯形(费用流)
传送门 费用流经典题. 按照题目要求建边. 为了方便我将所有格子拆点,三种情况下容量分别为111,infinfinf,infinfinf,费用都为validi,jval_{id_{i,j}}valid ...
- 洛谷P4003 无限之环(费用流)
传送门 神仙题啊……不看题解我可能一年都不一定做得出来……FlashHu大佬太强啦 到底是得有怎样的脑回路才能一眼看去就是费用流啊…… 建好图之后套个板子就好了,那么我们着重来讨论一下怎么建图 首先, ...
- 洛谷P4012 深海机器人问题(费用流)
题目描述 深海资源考察探险队的潜艇将到达深海的海底进行科学考察. 潜艇内有多个深海机器人.潜艇到达深海海底后,深海机器人将离开潜艇向预定目标移动. 深海机器人在移动中还必须沿途采集海底生物标本.沿途生 ...
随机推荐
- Python函数的进阶
一 函数的动态参数 *agrs 位置参数动态传参 *args 接收多个位置参数 def func(*args): print(args) func("女儿国","西 ...
- Win10系统windows mobile设备中心无法连接WinCE采集器
1.开始-->运行,输入services.msc回车 2.在打开的服务界面中,找到“基于Windows Mobile 2003的连接设备” 3.右击属性,修改成自动 4.点击登陆选项卡,选择本地 ...
- c作图-正弦函数图像
#include<graphics.h>#include<math.h>int main(){ int gmode,gdriver=DETECT; double x1,y ...
- RedHat Enterprise Linu…
Abstract 在嵌入式开发中有宿主机和目标机之分:宿主机是执行编译.链接嵌入式软件的计算机:目标机是运行嵌入式软件的硬件平台. TFTP服务器作为工作于宿主机的软件,主要提供对目标机的主要映像文件 ...
- 详解Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化
在数据库有外键的时候,使用 select_related() 和 prefetch_related() 可以很好的减少数据库请求的次数,从而提高性能.本文通过一个简单的例子详解这两个函数的作用. 1. ...
- java基础之多线程三:多线程并发同步
由于线程的执行是CPU随机调度的,比如我们开启10个线程,这10个线程并不是同时执行的,而是CPU快速的在这10个线程之间切换执行,由于切换速度极快使我们感觉同时执行罢了. 线程同步问题往往发生在多个 ...
- linux上搭建图片服务器
之前写过一个搭建图片服务器的随笔:https://www.cnblogs.com/xujingyang/p/7163290.html ,现在回头看看,我去,感觉写的好乱,现在再整一个吧.o(╯□╰ ...
- Shell +Cygwinterminal+WinMySQL 传参数授权
前言:新公司因为部分业务原因有好几百组win机器装MySQL授权登录比较麻烦,简单的写了一个shell传值自动授权的脚本,保存复用. #!/bin/bash #author liding@zlhy.c ...
- 19、SOAP安装,运用与比对结果解释
转载:http://www.dengfeilong.com/post/Soap2.html https://blog.csdn.net/zhu_si_tao/article/details/71108 ...
- linux操作小技巧
巧妙利用别称 alias,让工作更有效率 在我的个人目录下/home/zdwu,打开.bashrc文件进行修改: 将 ll='ls -alF' 改为 ll='ls -ahlF',是的观察的结果显示更 ...