2015 USP-ICMC gym 100733 I. The Cool Monkeys
The first mafia on planet Earth was actually composed of a bunch of cool jumping monkeys. The name of that group was pretty simple - Monkafia - and they dominated the food chain and the transport systems in the biggest tropical forest of the world at the time.
Tha typical Monkafia squadron was composed of a group of m monkeys. They had headquarters - usually composed of two trees. We will call those trees A and B. The monkeys slept on the highest branches of tree A, and, during morning, used to climb down to the lowest branches of tree B, alternating between branches of trees A and B. They could jump multiple times between the two trees.
Monkeys in the Monkafia are very irritating and don't like sharing, so they could never jump on a branch that another monkey had already jumped or been that morning.
We know that each branch of trees A and B has a certain height, H. It is possible for a monkey to jump from a branch Ga to a branch Gbonly if |HGa - HGb| < T, where T is the height a single monkey can jump.
It is not always possible for two arbitrary trees to have all monkeys of a Monkafia squadron jump down from the topmost branches of one of the trees to the bottommost branches of the other without breaking the rules. Given that, your job here is the following: given a pair o trees, with the heights of their branches and the distance T, find out if it is possible for the squadron to do the morning descend considering all the constraints. Any of the trees can be tree A (the starting tree) or tree B (the ending tree).
The input begins with four numbers, m, nA, nB e T (1 ≤ m ≤ nA, nB ≤ 500, 1 < T ≤ 108), the number of monkeys, the number of branches in one tree, the number of branches in the other tree and the distance the monkeys can jump. Follow na lines, each with the height of a branch from the first tree (1 ≤ HGa ≤ 108). Then follows nb lines, each with the height of a branch from the second tree (1 ≤ HGb ≤ 108).
Answer 'S' if it is possible to use that pair of trees and 'N' otherwise.
1 2 2 3
1
3
2
1
S
1 2 3 2
1
3
2
1
1
S
2 2 3 2
1
3
2
1
1
S
2 6 7 4
8
4
5
2
9
11
2
2
8
3
12
3
12
N
思路:拆点最大流裸题
1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cmath> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <stack> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <list> 16 #include <iomanip> 17 #include <cctype> 18 #include <cassert> 19 #include <bitset> 20 #include <ctime> 21 22 using namespace std; 23 24 #define pau system("pause") 25 #define ll long long 26 #define pii pair<int, int> 27 #define pb push_back 28 #define mp make_pair 29 #define clr(a, x) memset(a, x, sizeof(a)) 30 31 const double pi = acos(-1.0); 32 const int INF = 0x3f3f3f3f; 33 const int MOD = 1e9 + 7; 34 const double EPS = 1e-9; 35 const int Max_E = 3e6; 36 const int Max_V = 2e3; 37 /* 38 #include <ext/pb_ds/assoc_container.hpp> 39 #include <ext/pb_ds/tree_policy.hpp> 40 41 using namespace __gnu_pbds; 42 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T; 43 */ 44 45 int m, na, nb, T, aa[Max_V + 15], ab[Max_V + 15]; 46 struct Edge { 47 int u, v, w; 48 Edge () {} 49 Edge (int u, int v, int w) : u(u), v(v), w(w) {} 50 } e[Max_E + 15]; 51 int head[Max_V + 15], nex[Max_E + 15], tot; 52 void add_edge(int u, int v, int w) { 53 e[++tot] = Edge(u, v, w); 54 nex[tot] = head[u], head[u] = tot; 55 e[++tot] = Edge(v, u, 0); 56 nex[tot] = head[v], head[v] = tot; 57 } 58 void build(int arr1[], int arr2[], int na, int nb) { 59 tot = -1; 60 clr(head, -1), clr(nex, -1); 61 sort(arr1 + 1, arr1 + na + 1); 62 reverse(arr1 + 1, arr1 + na + 1); 63 sort(arr2 + 1, arr2 + nb + 1); 64 int s = 0; 65 for (int i = 1; i <= m; ++i) { 66 add_edge(s, i * 2 - 1, 1); 67 } 68 for (int i = 1; i <= na; ++i) { 69 add_edge(i * 2 - 1, i * 2, 1); 70 } 71 int t = 2 * (na + nb) + 1; 72 for (int i = 1; i <= m; ++i) { 73 add_edge(2 * na + 2 * i, t, 1); 74 } 75 for (int i = 1; i <= nb; ++i) { 76 add_edge(2 * na + 2 * i - 1, 2 * na + 2 * i, 1); 77 } 78 for (int i = 1; i <= na; ++i) { 79 for (int j = 1; j <= nb; ++j) { 80 if (abs(arr1[i] - arr2[j]) < T) { 81 add_edge(2 * i, 2 * na + 2 * j - 1, 1); 82 add_edge(2 * na + 2 * j, 2 * i - 1, 1); 83 } 84 } 85 } 86 } 87 int dep[Max_V + 15]; 88 queue<int> que; 89 bool bfs() { 90 clr(dep, 0); 91 while (que.size()) que.pop(); 92 que.push(0), dep[0] = 1; 93 while (que.size()) { 94 int x = que.front(); que.pop(); 95 if (x == 2 * na + 2 * nb + 1) return true; 96 for (int i = head[x]; ~i; i = nex[i]) { 97 int v = e[i].v, w = e[i].w; 98 if (w && !dep[v]) { 99 que.push(v); 100 dep[v] = dep[x] + 1; 101 } 102 } 103 } 104 return false; 105 } 106 int cur[Max_V + 15]; 107 int dfs(int x, int c) { 108 if (x == 2 * na + 2 * nb + 1) { 109 return c; 110 } 111 if (!c) return 0; 112 int res = 0; 113 for (int i = cur[x]; ~i; i = nex[i]) { 114 if (e[i].w && dep[e[i].v] == dep[x] + 1) { 115 int dd = dfs(e[i].v, min(c, e[i].w)); 116 e[i].w -= dd; 117 e[i ^ 1].w += dd; 118 res += dd; 119 c -= dd; 120 } 121 cur[x] = i; 122 } 123 return res; 124 } 125 int dinic() { 126 int res = 0; 127 while (bfs()) { 128 for (int i = 0; i <= 2 * (na + nb) + 1; ++i) { 129 cur[i] = head[i]; 130 } 131 res += dfs(0, MOD); 132 } 133 return res; 134 } 135 void solve() { 136 build(ab, aa, nb, na); 137 int res1 = dinic(); 138 build(aa, ab, na, nb); 139 int res2 = dinic(); 140 putchar(max(res1, res2) >= m ? 'S' : 'N'); 141 } 142 int main() { 143 scanf("%d%d%d%d", &m, &na, &nb, &T); 144 for (int i = 1; i <= na; ++i) { 145 scanf("%d", &aa[i]); 146 } 147 for (int i = 1; i <= nb; ++i) { 148 scanf("%d", &ab[i]); 149 } 150 solve(); 151 return 0; 152 }