LOJ6015「网络流 24 题
来源:互联网 发布:什么平板有windows系统 编辑:程序博客网 时间:2024/06/05 11:22
大家都很强, 可与之共勉 。
题意:
由于人类对自然资源的消耗,人们意识到大约在
现有
每一艘太空船从一个太空站驶往任一太空站耗时均为
初始时所有人全在地球上,太空船全在初始站。试设计一个算法,找出让所有人尽快地全部转移到月球上的运输方案。
题解:
这道题我们可以看得出天与天之间是独立的,而且每次状态的转移都是跨天的,所以我们可以将每一天拆分来看,(据说这叫分层图)每一天我们都有若干个中转站和地月,这样我们就能实现单向建图的目的了。
由于这道题的答案是具有单调性的,所以借助魔术球那道题的经验,我们通过枚举天数,每天新加节点连边跑最大流的方法来找到第一次最大流超过给定的k即可。
建图方法:
- 从源点向每一天的地球链接一条
+∞ 。 - 从每一天的月亮向汇点链接一条
+∞ 。 - 从上一天的每一个节点向当天的对应节点链接一条
+∞ 。(因为人们可以留在中转站等一等)。 - 针对每一艘飞船,获取其上一天的位置,再获取这一天的位置,在这两个点之间连一条容量为飞船满载人数的流。
- 每次新加一天然后跑到最大流超过
k 就是答案。
画图理解
# include <bits/stdc++.h># define oo 0x3f3f3f3f# define N 5005class Network {private : struct edge { int to, w, nxt ; edge ( ) { } edge ( int to, int w, int nxt ) : to ( to ), w ( w ), nxt ( nxt ) { } } g [60010 << 1] ; int head [N], cur [N], ecnt ; int S, T , dep [N] ; inline int dfs ( int u, int a ) { if ( u == T || ! a ) return a ; int flow = 0, v, f ; for ( int& i = cur [u] ; i ; i = g [i].nxt ) { v = g [i].to ; if ( dep [v] == dep [u] + 1 ) { f = dfs ( v, std :: min ( g [i].w, a - flow ) ) ; g [i].w -= f, g [i ^ 1].w += f ; flow += f ; if ( a == flow ) return a ; } } if ( ! flow ) dep [u] = -1 ; return flow ; } inline bool bfs ( int S, int T ) { static std :: queue < int > q ; memset ( dep, 0, sizeof ( int ) * ( T + 1 ) ) ; dep [S] = 1 ; q.push ( S ) ; while ( ! q.empty ( ) ) { int u = q.front ( ) ; q.pop ( ) ; for ( int i = head [u] ; i ; i = g [i].nxt ) { int& v = g [i].to ; if ( g [i].w && ! dep [v] ) { dep [v] = dep [u] + 1 ; q.push ( v ) ; } } } return dep [T] ; }public : Network ( ) { ecnt = 1 ; } inline void add_edge ( int u, int v, int w ) { g [++ ecnt] = edge ( v, w, head [u] ) ; head [u] = ecnt ; g [++ ecnt] = edge ( u, 0, head [v] ) ; head [v] = ecnt ; } inline void clear ( ) { ecnt = 1 ; memset ( head, 0, sizeof head ) ; } inline int dinic ( int S, int T ) { this -> S = S, this -> T = T ; static int rt = 0 ; while ( bfs ( S, T ) ) { memcpy ( cur, head, sizeof ( int ) * ( T + 1 ) ) ; rt += dfs ( S, 0x3f3f3f3f ) ; } return rt ; }} Lazer ;int h [31], r [31], s [31] [N] ;int main ( ) { int n, m, k ; scanf ( "%d%d%d", & n, & m, & k ) ; n += 2 ; for ( int i = 1 ; i <= m ; ++ i ) { scanf ( "%d%d", h + i, r + i ) ; for ( int j = 1 ; j <= r [i] ; ++ j ) { scanf ( "%d", s [i] + j ) ; s [i] [j] += 2 ; } } const int S = 5001, T = 5002 ; for ( int ans = 0 ; ; ++ ans ) { Lazer.add_edge ( S, ans * n + 2, oo ) ; Lazer.add_edge ( ans * n + 1, T, oo ) ; // moon ; if ( ans ) { for ( int i = 1 ; i <= n ; ++ i ) { Lazer.add_edge ( ( ans - 1 ) * n + i, ans * n + i, oo ) ; } for ( int i = 1 ; i <= m ; ++ i ) { Lazer.add_edge ( ( ans - 1 ) * n + s [i] [( ans - 1 ) % ( r [i] ) + 1], ans * n + s [i] [ans % ( r [i] ) + 1], h [i] ) ; } if ( Lazer.dinic ( S, T ) >= k ) { printf ( "%d\n", ans ) ; break ; } if ( ans > 100 ) { return puts ( "0" ), 0 ; } } }}
阅读全文
0 0
- LOJ6015「网络流 24 题
- loj6015「网络流 24 题」星际转移(枚举+分层图最大流)
- 【网络流】网络流24题
- [网络流]: 网络流24题
- 网络流24题
- 网络流24题
- 网络流24题
- 网络流24题
- 「网络流 24 题」试题库
- 「网络流 24 题」试题库
- LOJ6000 「网络流 24 题
- LOJ6001 「网络流 24 题
- LOJ6002 「网络流 24 题
- LOJ6003 「网络流 24 题
- LOJ6004 「网络流 24 题
- LOJ6005 「网络流 24 题
- LOJ6006「网络流 24 题
- LOJ6007 「网络流 24 题
- 面向对象程序设计初探
- Unity UI案例(长按按钮和双击按钮案例
- as报错UnsupportedOperationException
- MD5算法循环中为什么会有 & 0XFF
- 面试中的算法(java方向)
- LOJ6015「网络流 24 题
- Linux平台下交叉编辑器的理解
- DjangoURL name详解
- Linux下安装网卡驱动程序详解
- Hadoop大数据处理技术综合实验
- 纯html跨域访问java接口
- IDEA建空的项目(已有的项目架构)
- 用Tensorflow实现简单的KNN
- 输入三个数按从大到小排列