LOJ #6010. 「网络流 24 题」数字梯形

#6010. 「网络流 24 题」数字梯形

题目描述

给定一个由 n nn 行数字组成的数字梯形如下图所示。梯形的第一行有 m mm 个数字。从梯形的顶部的 m mm 个数字开始,在每个数字处可以沿左下或右下方向移动,形成一条从梯形的顶至底的路径。

分别遵守以下规则:

  1. 从梯形的顶至底的 m mm 条路径互不相交;
  2. 从梯形的顶至底的 m mm 条路径仅在数字结点处相交;
  3. 从梯形的顶至底的 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

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4
  5 using namespace std;
  6 const int N = 1010;
  7 const int INF = 1e9;
  8
  9 struct Edge{
 10     int u,v,f,c,nxt;
 11     Edge(){}
 12     Edge(int a,int b,int flow,int cost,int nt) {
 13         u = a;v = b;f = flow;c = cost;nxt = nt;
 14     }
 15 }e[100100];
 16 int head[N],dis[N],q[100100],pre[N],a[30][30],b[30][30];
 17 bool vis[N];
 18 int n,m,S,T,tn,L,R,Mc,ans,tot;
 19
 20 inline char nc() {
 21     static char buf[100000],*p1 = buf,*p2 = buf;
 22     return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2) ? EOF :*p1++;
 23 }
 24 inline int read() {
 25     int x = 0,f = 1;char ch=nc();
 26     for (; ch<‘0‘||ch>‘9‘; ch=nc()) if(ch==‘-‘)f=-1;
 27     for (; ch>=‘0‘&&ch<=‘9‘; ch=nc()) x=x*10+ch-‘0‘;
 28     return x*f;
 29 }
 30 void add_edge(int u,int v,int f,int c) {
 31     e[++tot] = Edge(u,v,f,c,head[u]);head[u] = tot;
 32     e[++tot] = Edge(v,u,0,-c,head[v]);head[v] = tot;
 33 }
 34 bool spfa() {
 35     for (int i=1; i<=T; ++i) vis[i]=false,dis[i]=INF;
 36     L = 1;R = 0;
 37     dis[S] = 0;
 38     q[++R] = S;vis[S] = true;pre[S] = 0;
 39     while (L <= R) {
 40         int u = q[L++];
 41         for (int i=head[u]; i; i=e[i].nxt) {
 42             int v = e[i].v;
 43             if (dis[v]>dis[u]+e[i].c && e[i].f > 0) {
 44                 dis[v] = dis[u] + e[i].c;
 45                 pre[v] = i;
 46                 if (!vis[v]) q[++R] = v,vis[v] = true;
 47             }
 48         }
 49         vis[u] = false;
 50     }
 51     return dis[T]!=INF;
 52 }
 53 void mcf() {
 54     int zf = INF;
 55     for (int i=T; i!=S; i=e[pre[i]].u)
 56         zf = min(zf,e[pre[i]].f);
 57     for (int i=T; i!=S; i=e[pre[i]].u)
 58         e[pre[i]].f -= zf,e[pre[i]^1].f += zf;
 59     Mc += dis[T]*zf;
 60 }
 61 int work() {
 62     Mc = 0;
 63     while (spfa()) mcf();
 64     printf("%d\n",-Mc);
 65 }
 66 void init() {
 67     tot = 1;
 68     memset(head,0,sizeof(head));
 69 }
 70 void build_1() {
 71     init();
 72     S = tn + tn + 1;T = tn + tn + 2;
 73     for (int i=1; i<=n; ++i)
 74         for (int j=1; j<=m+i-1; ++j) {
 75             add_edge(b[i][j],b[i][j]+tn,1,-a[i][j]);
 76             add_edge(b[i][j]+tn,b[i+1][j],1,0);
 77             add_edge(b[i][j]+tn,b[i+1][j+1],1,0);
 78             if (i==1) add_edge(S,b[i][j],1,0);
 79             if (i==n) add_edge(b[i][j]+tn,T,1,0);
 80         }
 81 }
 82 void build_2() {
 83     init();
 84     S = tn + 1;T = tn + 2;
 85     for (int i=1; i<=n; ++i) {
 86         for (int j=1; j<=m+i-1; ++j) {
 87             add_edge(b[i][j],b[i+1][j],1,-a[i][j]);
 88             add_edge(b[i][j],b[i+1][j+1],1,-a[i][j]);
 89             if (i==1) add_edge(S,b[i][j],1,0);
 90             if (i==n) add_edge(b[i][j],T,INF,-a[i][j]);
 91         }
 92     }
 93 }
 94 void build_3() {
 95     init();
 96     S = tn + 1;T = tn + 2;
 97     for (int i=1; i<=n; ++i) {
 98         for (int j=1; j<=m+i-1; ++j) {
 99             add_edge(b[i][j],b[i+1][j],INF,-a[i][j]);
100             add_edge(b[i][j],b[i+1][j+1],INF,-a[i][j]);
101             if (i==1) add_edge(S,b[i][j],1,0);
102             if (i==n) add_edge(b[i][j],T,INF,-a[i][j]);
103         }
104     }
105 }
106 int main() {
107     m = read(),n = read();
108     for (int i=1; i<=n; ++i)
109         for (int j=1; j<=m+i-1; ++j) a[i][j] = read(),b[i][j] = ++tn;
110
111     build_1();work();
112     build_2();work();
113     build_3();work();
114     return 0;
115 }

原文地址:https://www.cnblogs.com/mjtcn/p/8542325.html

时间: 2024-08-02 04:34:13

LOJ #6010. 「网络流 24 题」数字梯形的相关文章

「网络流 24 题」数字梯形

直接拆点做,但就是搞不懂为什么wa掉了第一小问.... 不管了 #include<bits/stdc++.h> using namespace std; long long tot=-1,sum=0,h[20005],flow[20005],g[20005],ans=0,dis[20005],ans2=0,inf=9999999; bool vis[20005]; struct node{ long long from,to,next,rest,cost; }e[10000005]; void

[loj #6003]「网络流 24 题」魔术球 二分图最小路径覆盖,网络流

#6003. 「网络流 24 题」魔术球 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 假设有 n nn 根柱子,现要按下述规则在这 n nn 根柱子中依次放入编号为 1,2,3,4,? 1, 2, 3, 4, \cdots1,2,3,4,? 的球. 每次只能在某根柱子的最上面放球. 在同一根柱子中,任何 2 22 个相邻球的编号之和为完全平方数. 试设计一个算法,计算出在

LOJ #6008. 「网络流 24 题」餐巾计划

#6008. 「网络流 24 题」餐巾计划 题目描述 一个餐厅在相继的 n nn 天里,每天需用的餐巾数不尽相同.假设第 i ii 天需要 ri r_ir?i?? 块餐巾.餐厅可以购买新的餐巾,每块餐巾的费用为 P PP 分:或者把旧餐巾送到快洗部,洗一块需 M MM天,其费用为 F FF 分:或者送到慢洗部,洗一块需 N NN 天,其费用为 S SS 分(S<F S < FS<F). 每天结束时,餐厅必须决定将多少块脏的餐巾送到快洗部,多少块餐巾送到慢洗部,以及多少块保存起来延期送洗.

Loj #6000.「 网络流 24 题 」搭配飞行员

放图片是不是很骚气 解题思路 建立超级源点和超级汇点.将主驾驶雨源点相连,副驾驶与汇点相连,再把输入的有向边加进去,同时建反边. 跑$Dinic$,网络流模板不难,难的是建模QAQ 附上代码 #include <iostream> #include <cstring> #include <cstdio> #include <queue> using namespace std; const int maxnode = 105, maxedge = 30003

*LOJ#6227. 「网络流 24 题」最长k可重线段集问题

$n \leq 500$条平面上的线段,问一种挑选方法,使得不存在直线$x=p$与挑选的直线有超过$k$个交点,且选得的直线总长度最长. 横坐标每个点开一个点,一条线段就把对应横坐标连一条容量一费用(-长度)的边:点$x$向点$x+1$连一条容量$k$费用0的边.这里的$k$边限制的是直线上其他不经过这里的地方. 这里有个trick就是有与$x$轴垂直的线段.直接判掉会wa.为此把坐标扩大两倍,如果$l=r$那么$r++$否则$l++$,相当于把一个点拆成两个. 原文地址:https://www

LiberOJ #6000. 「网络流 24 题」搭配飞行员 最大匹配

#6000. 「网络流 24 题」搭配飞行员 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 飞行大队有若干个来自各地的驾驶员,专门驾驶一种型号的飞机,这种飞机每架有两个驾驶员,需一个正驾驶员和一个副驾驶员.由于种种原因,例如相互配合的问题,有些驾驶员不能在同一架飞机上飞行,问如何搭配驾驶员才能使出航的飞机最多. 因为驾驶工作分工严格,两个正驾驶员或两个副驾驶员都不能同机飞行. 输入格式 第一

LibreOJ #6001. 「网络流 24 题」太空飞行计划 最大权闭合图

#6001. 「网络流 24 题」太空飞行计划 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利润.现已确定了一个可供选择的实验集合 E={E1,E2,?,Em} E = \{ E_1, E_2, \cdots, E_m \}E={E?1??,E?2??,?,E?m??},和进行这些实验

LiberOJ #6013. 「网络流 24 题」负载平衡 最小费用最大流 供应平衡问题

#6013. 「网络流 24 题」负载平衡 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 G 公司有 n nn 个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使 n nn 个仓库的库存数量相同.搬运货物时,只能在相邻的仓库之间搬运. 输入格式 文件的第 1 11 行中有 1 11 个正整数 n nn,表示有 n nn 个仓库.第 2 22 行中有 n nn 个

LiberOJ #6002. 「网络流 24 题」最小路径覆盖

#6002. 「网络流 24 题」最小路径覆盖 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 给定有向图 G=(V,E) G = (V, E)G=(V,E).设 P PP 是 G GG 的一个简单路(顶点不相交)的集合.如果 V VV 中每个顶点恰好在 P PP 的一条路上,则称 P PP 是 G GG 的一个路径覆盖.P PP 中路径可以从 V VV 的任何一个顶点开始,