-网络流-最大流- [洛谷 P1343]地震逃生

题目描述

汶川地震发生时,四川**中学正在上课,一看地震发生,老师们立刻带领x名学生逃跑,整个学校可以抽象地看成一个有向图,图中有n个点,m条边。1号点为教室,n号点为安全地带,每条边都只能容纳一定量的学生,超过楼就要倒塌,由于人数太多,校长决定让同学们分成几批逃生,只有第一批学生全部逃生完毕后,第二批学生才能从1号点出发逃生,现在请你帮校长算算,每批最多能运出多少个学生,x名学生分几批才能运完。
输入输出格式
输入格式:

第一行3个整数n,m,x(x<2^31,n<=200,m<=2000);以下m行,每行三个整数a,b,c(a1,a<>b,0描述一条边,分别代表从a点到b点有一条边,且可容纳c名学生。

输出格式:

两个整数,分别表示每批最多能运出多少个学生,x名学生分几批才能运完。如果无法到达目的地(n号点)则输出“Orz Ni Jinan Saint Cow!”

输入样例

6 7 7
1 2 1
1 4 2
2 3 1
4 5 1
4 3 1
3 6 2
5 6 1

输出样例

3 3

说明

比如有图

1 2 100

2 3 1

100个学生先冲到2号点,然后1个1个慢慢沿2-3边走过去

18神牛规定这样是不可以的……

也就是说,每批学生必须同时从起点出发,并且同时到达终点

Solution

这道题可以用最大流解决,然后再用总人数除以最大流量就可以了。

记住,如果有余数,就要+1毕竟剩下的人也是人啊

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
#define MAXN 1000002
#define INF 2000000000
namespace STman {
template <typename Tp>
inline void read(Tp &x) {
#define C getchar()
Tp f = 1;
x = 0;
char k = C;
while (k < '0' || k > '9') {
if (k == '-') f = -1;
k = C;
}
while (k >= '0' && k <= '9') {
x = x * 10 + k - '0';
k = C;
}
x = x * f;
#undef C
}
template <typename Tp>
inline void write(Tp x) {
if (x < 0) putchar('-') , x = -x;
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}
template <typename Tp>
inline Tp max(Tp a , Tp b) {
if (a > b) return a;
else return b;
}
template <typename Tp>
inline Tp min(Tp a , Tp b) {
if (a < b) return a;
else return b;
}
template <typename Tp>
inline void swap(Tp &a , Tp &b) {
Tp t = a;
a = b;
b = a;
}
template <typename Tp>
inline Tp abs(Tp &a) {
if (a < 0) return -a;
else return a;
}
inline void sp() {
putchar(32);
}
inline void et() {
putchar(10);
}
}
using namespace STman;
struct Edge {
int v , nx , w;
} e[MAXN];
std::queue <int> q;
int n , m , maxfl , total , head[MAXN] , ecnt = 1 , x , y , z , r , k , dep[MAXN] , cur[MAXN];
void add(int f , int t , int w) {
e[++ecnt] = (Edge) {t , head[f] , w};
head[f] = ecnt;
e[++ecnt] = (Edge) {f , head[t] , 0};
head[t] = ecnt;
}
bool bfs(int s , int t) {
memset(dep , 0x7f , sizeof(dep));
while (!q.empty()) q.pop();
for (int i = 1 ; i <= n ; i++) {
cur[i] = head[i];
}
dep[s] = 0;
q.push(s);
while (!q.empty()) {
int v = q.front();
q.pop();
for (int i = head[v] ; i ; i = e[i].nx) {
int to = e[i].v;
if (dep[to] > INF && e[i].w) {
dep[to] = dep[v] + 1;
q.push(to);
}
}
}
if (dep[t] < INF) return 1;
else return 0;
}
int dfs(int u , int t , int l) {
if (!l || u == t) return l;
int fl = 0 , f;
for (int i = cur[u] ; i ; i = e[i].nx) {
cur[u] = i;
int to = e[i].v;
if (dep[to] == dep[u] + 1 && (f = dfs(to , t , min(l , e[i].w)))) {
fl += f;
l -= f;
e[i ^ 1].w += f;
e[i].w -= f;
if (!l) break;
}
}
return fl;
}
int Dinic(int s , int t) {
int maxf = 0;
while (bfs(s , t)) {
maxf += dfs(s , t , INF);
}
return maxf;
}
int main() {
read(n) , read(m) , read(total);
r = 1;
k = n;
for (int i = 1 ; i <= m ; i++) {
read(x) , read(y) , read(z);
add(x , y , z);
}
maxfl = Dinic(r , k);
if (!maxfl) {
puts("Orz Ni Jinan Saint Cow!");
return 0;
}
write(maxfl) , sp();
write(total / maxfl + ((total % maxfl == 0) ? 0 : 1));
return 0;
}
文章作者: RiverFun
文章链接: https://stevebraveman.github.io/blog/2018/11/28/44/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 RiverFun

评论