Codeforces 513F1 513F2 Scaygerboss network stream, codeforces513f1
Question link: Click the open link
Question:
Map n * m to a man and B Women
The square map of n * m below indicates the space * indicates the obstacle.
The first line below shows the coordinates and moving time of the neutral person.
Line a below shows the coordinates and moving time of each man.
The following line B shows the coordinates and moving time of a woman.
Moving time refers to the time when a person moves to the adjacent matrix (a person cannot move to an obstacle)
There is exactly one house in each vacant space (a house can only be a couple, and others can still walk through the vacant space where people live ).
Goal: to allow everyone to form a couple and live in a house (a neutral person can form a couple with a male or a female)
The maximum time spent is the least, that is, the minimum time for the last person to live in the house.
Ideas:
If there is no transgender, this is a classic image,
The maximum time of the second part, and then create a graph.
Set now to the maximum time that each person can exercise
Man source node flow = 1
Flow = 1 (the time it takes for a man to walk to a house <= now)
House connected to women flow = 1
Women's connection point flow = 1
Because a house can only accommodate one person, the traffic limit is 1.
The gender of a gender is not randomly matched. It can be found only when abs (number of men-Number of Women) = 1, that is, gender of a gender can be determined at the beginning.
# Include <iostream> # include <stdio. h> # include <string. h >#include <queue >#include <cmath> template <class T> inline bool rd (T & ret) {char c; int sgn; if (c = getchar (), c = EOF) return 0; while (c! = '-' & (C <'0' | c> '9') c = getchar (); sgn = (c = '-')? -1: 1; ret = (c = '-')? 0: (c-'0'); while (c = getchar (), c> = '0' & c <= '9 ') ret = ret * 10 + (c-'0'); ret * = sgn; return 1;} template <class T> inline void pt (T x) {if (x <0) {putchar ('-'); x =-x;} if (x> 9) pt (x/10 ); putchar (x % 10 + '0');} using namespace std; typedef long ll; const ll inf = 1e10; const int N = 10019; const int M = 10000000; template <class T> struct Max_Flow {int n; int Q [N], sign; int head [N], level [N], Cur [N], pre [N]; int nxt [M], pnt [M], E; T cap [M]; void Init (int n) {this-> n = n + 1; E = 0; std: fill (head, head + this-> n,-1 );} // directed rw = 0 void add (int from, int to, T c, T rw) {pnt [E] = to; cap [E] = c; nxt [E] = head [from]; head [from] = E ++; pnt [E] = from; cap [E] = rw; nxt [E] = head [to]; head [to] = E ++;} bool Bfs (int s, int t) {sign = t; std :: fill (level, level + n,-1); int * front = Q, * tail = Q; * tail ++ = t; le Vel [t] = 0; while (front <tail & level [s] =-1) {int u = * front ++; for (int e = head [u]; e! =-1; e = nxt [e]) {if (cap [e ^ 1]> 0 & level [pnt [e] <0) {level [pnt [e] = level [u] + 1; * tail ++ = pnt [e] ;}} return level [s]! =-1;} void Push (int t, T & flow) {T mi = inf; int p = pre [t]; for (int p = pre [t]; p! =-1; p = pre [pnt [p ^ 1]) {mi = std: min (mi, cap [p]);} for (int p = pre [t]; p! =-1; p = pre [pnt [p ^ 1]) {cap [p]-= mi; if (! Cap [p]) {sign = pnt [p ^ 1];} cap [p ^ 1] + = mi;} flow + = mi;} void Dfs (int u, int t, T & flow) {if (u = t) {Push (t, flow); return;} for (int & e = cur [u]; e! =-1; e = nxt [e]) {if (cap [e]> 0 & level [u]-1 = level [pnt [e]) {pre [pnt [e] = e; Dfs (pnt [e], t, flow); if (level [sign]> level [u]) {return ;} sign = t ;}}t Dinic (int s, int T) {pre [s] =-1; t flow = 0; while (Bfs (s, T )) {std: copy (head, head + n, cur); Dfs (s, t, flow);} return flow ;}}; Max_Flow <ll> F; struct node {int x, y; ll t; node (int a = 0, int B = 0, ll c = 0): x (a), y (B ), t (c) {}} AA [N], B [N], C; int N, m, a, B; char mp [24] [24]; ll Dis [24] [24] [24]; int has1 (int x) {return x-1;} int has2 (int x, int y) {return a + (x-1) * m + y-1;} int has3 (int x, int y) {return a + n * m + (x-1) * m + y-1;} int has4 (int x) {return a + 2 * n * m + x-1;} bool OK (ll now) {int from = has4 (B) + 1, to = from + 1; F. init (to + 10); for (int I = 1; I <= a; I ++) {F. add (from, has1 (I), 1, 0); for (int x = 1; x <= n; x ++) (Int y = 1; y <= m; y ++) if (Dis [x] [y] [AA [I]. x] [AA [I]. y] <inf & Dis [x] [y] [AA [I]. x] [AA [I]. y] * AA [I]. t <= now) F. add (has1 (I), has2 (x, y), 1, 0) ;}for (int I = 1; I <= n; I ++) for (int j = 1; j <= m; j ++) if (mp [I] [j] = '. ') F. add (has2 (I, j), has3 (I, j), 1, 0); for (int I = 1; I <= B; I ++) {F. add (has4 (I), to, 1, 0); for (int x = 1; x <= n; x ++) for (int y = 1; y <= m; y ++) if (Dis [x] [y] [B [I]. x] [B [I]. y] <I Nf & Dis [x] [y] [B [I]. x] [B [I]. y] * B [I]. t <= now) F. add (has3 (x, y), has4 (I), 1, 0);} return F. dinic (from, to) = B;} ll solve () {if (! = B) return-1; ll ans =-1, l = 0, r = 1e18; while (l <= r) {ll mid = (l + r)> 1; if (OK (mid) {r = mid-1; ans = mid;} elsel = mid + 1;} return ans;} void pre () {for (int I = 1; I <= n; I ++) for (int j = 1; j <= m; j ++) for (int x = 1; x <= n; x ++) for (int y = 1; y <= m; y ++) dis [I] [j] [x] [y] = inf; int step [4] [2] = {0, 1, 0,-1, 1, 0, -1, 0}; for (int I = 1; I <= n; I ++) for (int j = 1; j <= m; j ++) {if (mp [I] [j] = '*') continue; Dis [I] [j] [I] [j] = 0; for (int k = 0; k <4; k ++) {int x = I + step [k] [0], y = j + step [k] [1]; if (1 <= x & x <= n & 1 <= y & y <= m & amp; mp [x] [y] = '. ') Dis [I] [j] [x] [y] = 1 ;}}for (int x1 = 1; x1 <= n; x1 ++) for (int y1 = 1; y1 <= m; y1 ++) if (mp [x1] [y1] = '. ') for (int x2 = 1; x2 <= n; x2 ++) for (int y2 = 1; y2 <= m; y2 ++) if (mp [x2] [y2] = '. '& Dis [x2] [y2] [x1] [y1] <inf) for (int x3 = 1; x3 <= n; x3 ++) for (int y3 = 1; y3 <= m; y3 ++) if (mp [x3] [y3] = '. ') Dis [x2] [y2] [x3] [y3] = min (Dis [x2] [y2] [x3] [y3], dis [x2] [y2] [x1] [y1] + Dis [x1] [y1] [x3] [y3]); if (a> B) B [++ B] = C; else AA [++ a] = C;} void input () {rd (n); rd (m); rd (); rd (B); for (int I = 1; I <= n; I ++) scanf ("% s", mp [I] + 1); rd (C. x); rd (C. y); rd (C. t); for (int I = 1; I <= a; I ++) {rd (AA [I]. x); rd (AA [I]. y); rd (AA [I]. t) ;}for (int I = 1; I <= B; I ++) {rd (B [I]. x); rd (B [I]. y); rd (B [I]. t) ;}} int main () {input (); pre (); cout <solve () <endl; return 0 ;}