洛谷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 深海机器人问题(费用流)
题目描述 深海资源考察探险队的潜艇将到达深海的海底进行科学考察. 潜艇内有多个深海机器人.潜艇到达深海海底后,深海机器人将离开潜艇向预定目标移动. 深海机器人在移动中还必须沿途采集海底生物标本.沿途生 ...
随机推荐
- git apply、git am打补丁.diff 和 .patch【转】
本文转载自:https://www.jianshu.com/p/e5d801b936b6 前提: 生成patch: git format-patch -M master 生成指定patch,0163b ...
- repo 工具下载 以及 android代码下载【转】
本文转载自:http://www.enjoydiy.com/608.html 我们可以从https://www.codeaurora.org/网站下载android源码. 具体方法如下: 下载repo ...
- Android Studio运行出现项目 错误:非法字符:“\ufeff”
导入项目时,遇到编码问题. 主要原因是: eclipse可以自动把UTF-8+BOM文件转为普通的UTF-8文件,但Android Studio需要重新转换一下编码 解决方法: 将编码格式UTF-8+ ...
- Ubuntu 12.04 nethogs 流量监控查看
/*************************************************************** * Ubuntu 12.04 流量监控查看 * 说明: * 今天打算从 ...
- [SDOI2016] 模式字符串 (BZOJ4598 & VIJOS1995)
首先直接点分+hash就可以做,每个点用hash判断是否为S重复若干次后的前缀或后缀,每个子树与之前的结果O(m)暴力合并.在子树大小<m时停止分治,则总复杂度为O(nlog(n/m)). 问题 ...
- AndroidStudio修改主题外观和字体大小
修改主题外观 File --> Settings --> Appearance & Behavior --> Appearance 右边 Theme 修改编辑器的字体大小 F ...
- WebService安全解决方案—简单握手协议
具体方案如下图: 2.解决方案分析 A.SiteA每次向SiteB发送的请求参数都不一样,造成伪造者难以模仿和推敲里面的算法过程. B.伪造者获得了SayHelloRequest的数据,它向SiteB ...
- gitbucket
github固然强大,但不怎么适合企业级的开发版本管理,原因相信大家都明白,首先在github上上传和拉取代码速度是比较慢的,再者,在Github上创建一个私有仓库是收费的,那么gitbucket是一 ...
- django上课笔记7-jQuery Ajax 和 原生Ajax-伪造的Ajax-三种Ajax上传文件方法-JSONP和CORS跨域资源共享
一.jQuery Ajax 和 原生Ajax from django.conf.urls import url from django.contrib import admin from app01 ...
- NYOJ8——一种排序
一种排序 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述:现在有很多长方形,每一个长方形都有一个编号,这个编号可以重复:还知道这个长方形的宽和长,编号.长.宽都是整数: ...