洛谷P4013 数字梯形问题(费用流)
题意
$N$行的矩阵,第一行有$M$个元素,第$i$行有$M + i - 1$个元素
问在三个规则下怎么取使得权值最大

Sol
我只会第一问qwq。。
因为有数量的限制,考虑拆点建图,把每个点拆为$a_1$和$b_1$,两点之间连流量为$1$,费用为权值的边
从$b_i$向下方和右下的$a_1$连一条流量为$1$,费用为$0$边
从$S$向第一层的$a_1$连流量为$1$,费用为$0$的边,从$b_N$到$T$连流量为$1$,费用为$0$的边
对于第二问,因为没有点的个数的限制,那么就不用拆点了,直接向能到达的点连流量为$1$,费用为点权的边
对于第三问,直接把第二问中的所有边为流量设为$INF$(除了从$S$出发的)
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int MAXN = 1e5 + , INF = 1e9 + ;
inline int read() {
char c = getchar(); int x = , f = ;
while(c < '' || c > '') {if(c == '-') f = ; c = getchar();}
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * f;
}
int N, M, S = , T = 1e5 + ;
int a[][];
struct Edge {
int u, v, w, f, nxt;
}E[MAXN];
int head[MAXN << ], num = ;
inline void add_edge(int x, int y, int w, int f) { E[num] = (Edge){x, y, w, f, head[x]};
head[x] = num++;
}
inline void AddEdge(int x, int y, int w, int f) {
add_edge(x, y, w, f);
add_edge(y, x, -w, );
}
int anscost, dis[MAXN], vis[MAXN], Pre[MAXN];
bool SPFA() {
memset(dis, -0x3f, sizeof(dis));
memset(vis, , sizeof(vis));
queue<int> q; q.push(S); dis[S] = ;
while(!q.empty()) {
int p = q.front(); q.pop(); vis[p] = ;
for(int i = head[p]; i !=- ; i = E[i].nxt) {
int to = E[i].v;
if((dis[to] < dis[p] + E[i].w) && E[i].f > ) {
dis[to] = dis[p] + E[i].w;
Pre[to] = i;
if(!vis[to]) q.push(to), vis[to] = ;
}
}
}
return dis[T] > ;
}
int F() {
int nowflow = INF;
for(int i = T; i != S; i = E[Pre[i]].u) nowflow = min(nowflow, E[Pre[i]].f);
for(int i = T; i != S; i = E[Pre[i]].u) E[Pre[i]].f -= nowflow, E[Pre[i] ^ ].f += nowflow;
anscost += dis[T] * nowflow;
}
int MCMF() {
anscost = ;
while(SPFA())
F();
return anscost;
}
int be[][], tot = , X;
void Solve1() {
memset(head, -, sizeof(head)); num = ;
for(int i = ; i < N; i++) {
for(int j = ; j <= M + i - ; j++) {
AddEdge(be[i][j], be[i][j] + X, a[i][j], );
AddEdge(be[i][j] + X, be[i + ][j], , );
AddEdge(be[i][j] + X, be[i + ][j + ], , );
}
}
for(int i = ; i <= M; i++) AddEdge(S, be[][i], , );
for(int i = ; i <= N + M - ; i++)
AddEdge(be[N][i], be[N][i] + X, a[N][i], ),
AddEdge(be[N][i] + X, T, , );
printf("%d\n", MCMF());
}
void Solve2() {
memset(head, -, sizeof(head)); num = ;
for(int i = ; i < N; i++) {
for(int j = ; j <= M + i - ; j++) {
AddEdge(be[i][j], be[i + ][j + ], a[i][j], );
AddEdge(be[i][j], be[i + ][j], a[i][j], );
}
}
for(int i = ; i <= M; i++) AddEdge(S, be[][i], , );
for(int i = ; i <= N + M - ; i++) AddEdge(be[N][i], T, a[N][i], INF);
printf("%d\n", MCMF());
}
void Solve3() {
memset(head, -, sizeof(head)); num = ;
for(int i = ; i < N; i++)
for(int j = ; j <= M + i - ; j++) {
AddEdge(be[i][j], be[i + ][j + ], a[i][j], INF);
AddEdge(be[i][j], be[i + ][j], a[i][j], INF);
}
for(int i = ; i <= M; i++) AddEdge(S, be[][i], , );
for(int i = ; i <= N + M - ; i++) AddEdge(be[N][i], T, a[N][i], INF);
printf("%d\n", MCMF());
}
int main() {
memset(head, -, sizeof(head));
M = read(); N = read(); X = (N + M - ) * N;
for(int i = ; i <= N; i++)
for(int j = ; j <= M + i - ; j++)
a[i][j] = read(), be[i][j] = ++tot;
Solve1();
Solve2();
Solve3();
return ;
}
/* */
洛谷P4013 数字梯形问题(费用流)的更多相关文章
- 洛谷P4013 数字梯形问题(费用流)
传送门 两个感受:码量感人……大佬nb…… 规则一:$m$条路径都不相交,那么每一个点只能经过一次,那么考虑拆点,把每一个点拆成$A_{i,j}$和$B_{i,j}$,然后两点之间连一条容量$1$,费 ...
- 洛谷 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 深海机器人问题(费用流)
题目描述 深海资源考察探险队的潜艇将到达深海的海底进行科学考察. 潜艇内有多个深海机器人.潜艇到达深海海底后,深海机器人将离开潜艇向预定目标移动. 深海机器人在移动中还必须沿途采集海底生物标本.沿途生 ...
随机推荐
- NOIP2016总结
Day1: T1:模拟: #include<iostream> #include<cstdio> #include<cstdlib> #include<cst ...
- docker pure-ftp 搭建ftp服务器
参考:https://hub.docker.com/r/stilliard/pure-ftpd/ docker-compose.yml: ftp: image: stilliard/pure-ftpd ...
- 数据结构之 图论---图的深度遍历( 输出dfs的先后遍历序列 )
图的深度遍历 Time Limit: 1000MS Memory limit: 65536K 题目描述 请定一个无向图,顶点编号从0到n-1,用深度优先搜索(DFS),遍历并输出.遍历时,先遍历节点编 ...
- YTU 2421: C语言习题 矩形法求定积分
2421: C语言习题 矩形法求定积分 时间限制: 1 Sec 内存限制: 128 MB 提交: 354 解决: 234 题目描述 写一个用矩形法求定积分的通用函数,分别求 (说明: sin,co ...
- apache日志信息详解
一.访问日志的格式 Apache内建了记录服务器活动的功能,这就是它的日志功能.下文详细介绍Apache的访问日志.错误日志.以及如何分析日志数据,如何定制Apache日志,如何从日志数据生成统计报 ...
- 任务35:JWT 认证授权介绍
任务35:JWT 认证授权介绍 应用场景主要是移动端或者PC端前后分离的场景 直接对客户端API的请求 例如访问admin/Index 没有权限返回403. 需要客户端手动的再发动请求,这是一个拿to ...
- SpringIOC 二—— 容器 和 Bean的深入理解
上文:Spring IOC 一--容器装配Bean的简单使用 上篇文章介绍了 Spring IOC 中最重要的两个概念--容器和Bean,以及如何使用 Spring 容器装配Bean.本文接着记录 S ...
- ASP.NET Core MVC 打造一个简单的图书馆管理系统 (修正版)(七) 学生信息增删
前言: 本系列文章主要为我之前所学知识的一次微小的实践,以我学校图书馆管理系统为雏形所作. 本系列文章主要参考资料: 微软文档:https://docs.microsoft.com/zh-cn/asp ...
- hdoj3711【水】
题意: 给你两个集合,对于每个B集合的元素,从A集合找一个数使得a^b的二进制的1个数最少. 思路: 直接搞= = #include <bits/stdc++.h> using names ...
- 图论之最短路算法之SPFA算法
SPFA(Shortest Path Faster Algorithm)算法,是一种求最短路的算法. SPFA的思路及写法和BFS有相同的地方,我就举一道例题(洛谷--P3371 [模板]单源最短路径 ...