LOJ #6010. 「网络流 24 题」数字梯形
#6010. 「网络流 24 题」数字梯形
题目描述
给定一个由 n nn 行数字组成的数字梯形如下图所示。梯形的第一行有 m mm 个数字。从梯形的顶部的 m mm 个数字开始,在每个数字处可以沿左下或右下方向移动,形成一条从梯形的顶至底的路径。
分别遵守以下规则:
- 从梯形的顶至底的 m mm 条路径互不相交;
- 从梯形的顶至底的 m mm 条路径仅在数字结点处相交;
- 从梯形的顶至底的 m mm 条路径允许在数字结点相交或边相交。
输入格式
第 1 11 行中有 2 22 个正整数 m mm 和 n nn,分别表示数字梯形的第一行有 m mm 个数字,共有 n nn 行。接下来的 n nn 行是数字梯形中各行的数字。
第 1 11 行有 m mm 个数字,第 2 22 行有 m+1 m + 1m+1 个数字 ……
输出格式
将按照规则 1,规则 2,和规则 3 计算出的最大数字总和并输出,每行一个最大总和。
样例
样例输入
2 5
2 3
3 4 5
9 10 9 1
1 1 10 1 1
1 1 10 12 1 1
样例输出
66
75
77
数据范围与提示
1≤m,n≤20 1 \leq m, n \leq 201≤m,n≤20
code
#include<cstdio>
#include<algorithm>
#include<cstring> using namespace std;
const int N = ;
const int INF = 1e9; struct Edge{
int u,v,f,c,nxt;
Edge(){}
Edge(int a,int b,int flow,int cost,int nt) {
u = a;v = b;f = flow;c = cost;nxt = nt;
}
}e[];
int head[N],dis[N],q[],pre[N],a[][],b[][];
bool vis[N];
int n,m,S,T,tn,L,R,Mc,ans,tot; inline char nc() {
static char buf[],*p1 = buf,*p2 = buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,,,stdin),p1==p2) ? EOF :*p1++;
}
inline int read() {
int x = ,f = ;char ch=nc();
for (; ch<''||ch>''; ch=nc()) if(ch=='-')f=-;
for (; ch>=''&&ch<=''; ch=nc()) x=x*+ch-'';
return x*f;
}
void add_edge(int u,int v,int f,int c) {
e[++tot] = Edge(u,v,f,c,head[u]);head[u] = tot;
e[++tot] = Edge(v,u,,-c,head[v]);head[v] = tot;
}
bool spfa() {
for (int i=; i<=T; ++i) vis[i]=false,dis[i]=INF;
L = ;R = ;
dis[S] = ;
q[++R] = S;vis[S] = true;pre[S] = ;
while (L <= R) {
int u = q[L++];
for (int i=head[u]; i; i=e[i].nxt) {
int v = e[i].v;
if (dis[v]>dis[u]+e[i].c && e[i].f > ) {
dis[v] = dis[u] + e[i].c;
pre[v] = i;
if (!vis[v]) q[++R] = v,vis[v] = true;
}
}
vis[u] = false;
}
return dis[T]!=INF;
}
void mcf() {
int zf = INF;
for (int i=T; i!=S; i=e[pre[i]].u)
zf = min(zf,e[pre[i]].f);
for (int i=T; i!=S; i=e[pre[i]].u)
e[pre[i]].f -= zf,e[pre[i]^].f += zf;
Mc += dis[T]*zf;
}
int work() {
Mc = ;
while (spfa()) mcf();
printf("%d\n",-Mc);
}
void init() {
tot = ;
memset(head,,sizeof(head));
}
void build_1() {
init();
S = tn + tn + ;T = tn + tn + ;
for (int i=; i<=n; ++i)
for (int j=; j<=m+i-; ++j) {
add_edge(b[i][j],b[i][j]+tn,,-a[i][j]);
add_edge(b[i][j]+tn,b[i+][j],,);
add_edge(b[i][j]+tn,b[i+][j+],,);
if (i==) add_edge(S,b[i][j],,);
if (i==n) add_edge(b[i][j]+tn,T,,);
}
}
void build_2() {
init();
S = tn + ;T = tn + ;
for (int i=; i<=n; ++i) {
for (int j=; j<=m+i-; ++j) {
add_edge(b[i][j],b[i+][j],,-a[i][j]);
add_edge(b[i][j],b[i+][j+],,-a[i][j]);
if (i==) add_edge(S,b[i][j],,);
if (i==n) add_edge(b[i][j],T,INF,-a[i][j]);
}
}
}
void build_3() {
init();
S = tn + ;T = tn + ;
for (int i=; i<=n; ++i) {
for (int j=; j<=m+i-; ++j) {
add_edge(b[i][j],b[i+][j],INF,-a[i][j]);
add_edge(b[i][j],b[i+][j+],INF,-a[i][j]);
if (i==) add_edge(S,b[i][j],,);
if (i==n) add_edge(b[i][j],T,INF,-a[i][j]);
}
}
}
int main() {
m = read(),n = read();
for (int i=; i<=n; ++i)
for (int j=; j<=m+i-; ++j) a[i][j] = read(),b[i][j] = ++tn; build_1();work();
build_2();work();
build_3();work();
return ;
}
LOJ #6010. 「网络流 24 题」数字梯形的更多相关文章
- 【刷题】LOJ 6010 「网络流 24 题」数字梯形
题目描述 给定一个由 \(n\) 行数字组成的数字梯形如下图所示.梯形的第一行有 \(m\) 个数字.从梯形的顶部的 \(m\) 个数字开始,在每个数字处可以沿左下或右下方向移动,形成一条从梯形的顶至 ...
- 2018.10.15 loj#6010. 「网络流 24 题」数字梯形(费用流)
传送门 费用流经典题. 按照题目要求建边. 为了方便我将所有格子拆点,三种情况下容量分别为111,infinfinf,infinfinf,费用都为validi,jval_{id_{i,j}}valid ...
- Libre 6010「网络流 24 题」数字梯形 (网络流,最大费用最大流)
Libre 6010「网络流 24 题」数字梯形 (网络流,最大费用最大流) Description 给定一个由n 行数字组成的数字梯形如下图所示.梯形的第一行有m 个数字.从梯形的顶部的m 个数字开 ...
- 【刷题】LOJ 6227 「网络流 24 题」最长k可重线段集问题
题目描述 给定平面 \(\text{xoy}\) 上 \(n\) 个开线段组成的集合 \(\text{I}\) ,和一个正整数 \(k\) ,试设计一个算法. 从开线段集合 \(\text{I}\) ...
- [luogu_P1251][LOJ#6008]「网络流 24 题」餐巾计划
[luogu_P1251][LOJ#6008]「网络流 24 题」餐巾计划 试题描述 一个餐厅在相继的 \(N\) 天里,第 \(i\) 天需要 \(R_i\) 块餐巾 \((i=l,2,-,N)\) ...
- [LOJ#6002]「网络流 24 题」最小路径覆盖
[LOJ#6002]「网络流 24 题」最小路径覆盖 试题描述 给定有向图 G=(V,E).设 P 是 G 的一个简单路(顶点不相交)的集合.如果 V 中每个顶点恰好在 P 的一条路上,则称 P 是 ...
- loj #6014. 「网络流 24 题」最长 k 可重区间集
#6014. 「网络流 24 题」最长 k 可重区间集 题目描述 给定实直线 L LL 上 n nn 个开区间组成的集合 I II,和一个正整数 k kk,试设计一个算法,从开区间集合 I II 中选 ...
- loj #6013. 「网络流 24 题」负载平衡
#6013. 「网络流 24 题」负载平衡 题目描述 G 公司有 n nn 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使 n nn 个仓库的库存数量相同.搬运货物时 ...
- loj #6122. 「网络流 24 题」航空路线问题
#6122. 「网络流 24 题」航空路线问题 题目描述 给定一张航空图,图中顶点代表城市,边代表两个城市间的直通航线.现要求找出一条满足下述限制条件的且途经城市最多的旅行路线. 从最西端城市出发,单 ...
随机推荐
- 【Android开发笔记】底部菜单栏 FragmentTabHost
公司项目,需求本来是按照谷歌官方指南写的,菜单栏设计成在导航栏下方 结果呢,审评时,BOSS为了和iOS统一,改成了底部菜单栏(标准结局),我只能呵呵呵呵呵呵呵 查了查资料发现实现底部菜单栏用的是Fr ...
- uLua学习之读取外部Lua脚本(四)
前言 上节说到了Lua脚本与unity3d中C#脚本的数据交互,但是我感觉上节中的数理方式不太好,因为我们是把Lua脚本以字符串形式粘贴到C#脚本中的,如果读取配置数据都这样做的话,那就太可怕了.想想 ...
- 【C++】【MFC】创建新的线程函数
DWORD WINAPI MyThreadProc (LPVOID lpParam){ somestruct* pN = (somestruct*)lpParam; // 将参数转为你的类型 ... ...
- 使用Loadrunner监控Windows资源
为了区分把装有loadrunner的机器称作A,被监控资源的服务器(windows)称作B 1.确保B机器Administrator账户是可使用状态:右键计算机→ 管理→ 本地用户和组→ 用户,其中A ...
- COGS 1191. [Tyvj Feb11] 猫咪的进化
★ 输入文件:neko.in 输出文件:neko.out 简单对比时间限制:1 s 内存限制:128 MB [背景] 对于一只猫咪来说,它是有九条命的.但是并不是所有的猫咪都是这样,只 ...
- pat甲级1020中序后序求层序
1020 Tree Traversals (25)(25 分) Suppose that all the keys in a binary tree are distinct positive int ...
- java Vamei快速教程19 嵌套类
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 到现在为止,我们都是在Java文件中直接定义类.这样的类出现在包(package) ...
- V2EX 神回复 #1
"抠图"用英文怎么说 今天突然被"抠图"这个单词给难住了," image segmentation "," image cut & ...
- IOS PickerView使用
- (void)viewDidLoad { [super viewDidLoad]; // 1.创建pickerview // pickerview有默认的frame UIPickerView *pi ...
- python __getattr__ __setattr__
class Rectangle: def __init__(self): self.width = 0 self.height = 0 def __setattr__(self, key, value ...