From 4542fc7abb22880848e75f5e45d7443da99cfa09 Mon Sep 17 00:00:00 2001
From: Bruno Freitas Tissei <bft15@inf.ufpr.br>
Date: Tue, 5 Mar 2019 15:39:43 -0300
Subject: [PATCH] Add things

Signed-off-by: Bruno Freitas Tissei <bft15@inf.ufpr.br>
---
 algorithms/graph/dinic.cpp          |  10 +-
 algorithms/graph/edmonds_karp.cpp   |   4 +-
 algorithms/graph/ford_fulkerson.cpp |   6 +-
 algorithms/graph/hopcroft_karp.cpp  |   2 +-
 algorithms/structure/avl.cpp        |  12 +--
 algorithms/structure/ball_tree.cpp  |   4 +-
 contests/ICPC_SA17/C.cpp            |   1 -
 contests/ICPC_SA17/E.cpp            |   2 +-
 contests/ICPC_SA17/I.cpp            |   2 +
 contests/SBC18/G.cpp                | 155 ++++++++++++++++++++++++++++
 10 files changed, 177 insertions(+), 21 deletions(-)
 create mode 100644 contests/SBC18/G.cpp

diff --git a/algorithms/graph/dinic.cpp b/algorithms/graph/dinic.cpp
index 2cadd90..82d9fd6 100644
--- a/algorithms/graph/dinic.cpp
+++ b/algorithms/graph/dinic.cpp
@@ -7,7 +7,7 @@
 
 // Edge struct to be used in adjacency list similar to vector<ii> graph[MAX], 
 // but storing more information than ii
-typedef struct edge {
+struct edge {
   int u;
   int flow, cap;
 
@@ -17,7 +17,7 @@ typedef struct edge {
   edge(int u, int flow, int cap, int rev) :
     u(u), flow(flow), cap(cap), rev(rev)
   {}
-} egde;
+};
 
 
 int depth[MAX];
@@ -27,8 +27,8 @@ vector<edge> graph[MAX];
 
 // Adds edge between s and t with capacity c
 void add_edge(int s, int t, int c) {
-  edge forward(t, 0, c, graph[t].sz);
-  edge backward(s, 0, 0, graph[s].sz);
+  edge forward(t, 0, c, graph[t].size());
+  edge backward(s, 0, 0, graph[s].size());
 
   graph[s].pb(forward);
   graph[t].pb(backward);
@@ -65,7 +65,7 @@ int dfs(int s, int t, int flow) {
     return flow;
 
   // Start iteration from where it last stopped to avoid repetitions
-  for ( ; start[s] < graph[s].sz; ++start[s]) {
+  for ( ; start[s] < graph[s].size(); ++start[s]) {
     edge &e = graph[s][start[s]];
 
     // If the next vertex is further from the source (and closer to the sink)
diff --git a/algorithms/graph/edmonds_karp.cpp b/algorithms/graph/edmonds_karp.cpp
index f9a2de6..1226290 100644
--- a/algorithms/graph/edmonds_karp.cpp
+++ b/algorithms/graph/edmonds_karp.cpp
@@ -13,7 +13,7 @@ bool cont[MAX];
 
 // Finds if there's a path between s and t using non-full
 // residual edges
-bool path(int s, int t) {
+bool bfs(int s, int t) {
   queue<int> Q;
   Q.push(s);
   cont[s] = true;
@@ -45,7 +45,7 @@ int edmonds_karp(int s, int t) {
   memcpy(rg, graph, sizeof(graph));
 
   // Repeat while there's a valid path between s and t
-  while (path(s, t)) {
+  while (bfs(s, t)) {
     int flow = inf;
 
     // Get the minimum capacity among all edges of the chosen path
diff --git a/algorithms/graph/ford_fulkerson.cpp b/algorithms/graph/ford_fulkerson.cpp
index 871b2ce..5e9eee5 100644
--- a/algorithms/graph/ford_fulkerson.cpp
+++ b/algorithms/graph/ford_fulkerson.cpp
@@ -13,7 +13,7 @@ bool cont[MAX];
 
 // Finds if there's a path between s and t using non-full
 // residual edges
-bool path(int s, int t) {
+bool dfs(int s, int t) {
   cont[s] = true;
   if (s == t)
     return true;
@@ -22,7 +22,7 @@ bool path(int s, int t) {
     if (!cont[i] && rg[s][i]) {
       par[i] = s;
 
-      if (path(i, t)) 
+      if (dfs(i, t)) 
         return true;
     }
 
@@ -39,7 +39,7 @@ int ford_fulkerson(int s, int t) {
   memcpy(rg, graph, sizeof(graph));
 
   // Repeat while there's a valid path between s and t
-  while (path(s, t)) {
+  while (dfs(s, t)) {
     int flow = inf;
 
     // Get the minimum capacity among all edges of the chosen path
diff --git a/algorithms/graph/hopcroft_karp.cpp b/algorithms/graph/hopcroft_karp.cpp
index 0969bde..ec36bac 100644
--- a/algorithms/graph/hopcroft_karp.cpp
+++ b/algorithms/graph/hopcroft_karp.cpp
@@ -1,7 +1,7 @@
 /**
  * Hopcroft-Karp
  *
- * Complexity (Time): O(E * sqrt(V))
+ * Complexity (Time): O(E*sqrt(V))
  * Complexity (Space): O(V + E)
  */
 
diff --git a/algorithms/structure/avl.cpp b/algorithms/structure/avl.cpp
index ee11442..97820ac 100644
--- a/algorithms/structure/avl.cpp
+++ b/algorithms/structure/avl.cpp
@@ -5,19 +5,19 @@
  * Complexity (Space): O(n)
  */
 
-typedef struct avl_node_t {
+struct avl_node_t {
   int key;
   int size;    // number of nodes bellow (optional)
   int height;  // height of node
 
-  struct avl_node_t *left;
-  struct avl_node_t *right;
-} avl_node_t;
+  avl_node_t *left;
+  avl_node_t *right;
+};
 
 
-typedef struct avl_t {
+struct avl_t {
   avl_node_t *root;
-} avl_t;
+};
 
 
 static inline int get_height(avl_node_t *node) {
diff --git a/algorithms/structure/ball_tree.cpp b/algorithms/structure/ball_tree.cpp
index 9518ea5..a515b6f 100644
--- a/algorithms/structure/ball_tree.cpp
+++ b/algorithms/structure/ball_tree.cpp
@@ -11,12 +11,12 @@
 typedef pair<double, double> point;
 typedef vector<point> pset;
 
-typedef struct node {
+struct node {
   double radius;
   point center;
 
   node *left, *right;
-} node;
+};
 
 
 double distance(point &a, point &b) {
diff --git a/contests/ICPC_SA17/C.cpp b/contests/ICPC_SA17/C.cpp
index 8503489..ca3d8ca 100644
--- a/contests/ICPC_SA17/C.cpp
+++ b/contests/ICPC_SA17/C.cpp
@@ -43,7 +43,6 @@ int main() {
     assert(false);
   };
 
-
   int flo = n / k;
   int cei = (n - 1) / k + 1;
 
diff --git a/contests/ICPC_SA17/E.cpp b/contests/ICPC_SA17/E.cpp
index 7f15659..cd14793 100644
--- a/contests/ICPC_SA17/E.cpp
+++ b/contests/ICPC_SA17/E.cpp
@@ -45,6 +45,7 @@ bool solve(int i, int r) {
   return dp[i][r] = false;
 }
 
+
 int main() {
   ios::sync_with_stdio(0);
   cin.tie(0);
@@ -55,4 +56,3 @@ int main() {
   cout << (!solve(0, 0) ? "*" : s) << ende;
   return 0;
 }
-
diff --git a/contests/ICPC_SA17/I.cpp b/contests/ICPC_SA17/I.cpp
index 4335b4a..41f470e 100644
--- a/contests/ICPC_SA17/I.cpp
+++ b/contests/ICPC_SA17/I.cpp
@@ -141,12 +141,14 @@ int query(int p, int q) {
   else return max(ans, max(cost[p][0], cost[q][0]));
 }
 
+
 int main() {
   ios::sync_with_stdio(0);
   cin.tie(0);
 
   int n, r; cin >> n >> r;
   map<ii,int> M;
+
   for (int i = 0; i < r; ++i) {
     int a, b, c; cin >> a >> b >> c;
     a--, b--;
diff --git a/contests/SBC18/G.cpp b/contests/SBC18/G.cpp
new file mode 100644
index 0000000..736aa39
--- /dev/null
+++ b/contests/SBC18/G.cpp
@@ -0,0 +1,155 @@
+#include <bits/stdc++.h>
+
+#define MAX 3010
+#define EPS 1e-6
+#define MOD 1000000007
+#define inf 0x3f3f3f3f
+#define llinf 0x3f3f3f3f3f3f3f3f
+
+#define fi first
+#define se second
+#define pb push_back
+#define ende '\n'
+
+#define all(x) (x).begin(), (x).end()
+#define rall(x) (x).rbegin(), (x).rend()
+#define mset(x, y) memset(&x, (y), sizeof(x))
+
+using namespace std; 
+
+typedef long long ll;
+typedef pair<int,int> ii;
+
+struct edge {
+  int u;
+  int flow, cap;
+  int rev;
+
+  edge(int u, int flow, int cap, int rev) :
+    u(u), flow(flow), cap(cap), rev(rev)
+  {}
+};
+
+
+int depth[MAX];
+int start[MAX];
+vector<edge> graph[MAX];
+
+
+void add_edge(int s, int t, int c) {
+  edge forward(t, 0, c, graph[t].size());
+  edge backward(s, 0, 0, graph[s].size());
+
+  graph[s].pb(forward);
+  graph[t].pb(backward);
+}
+
+
+bool bfs(int s, int t) {
+  queue<int> Q;
+  Q.push(s);
+
+  mset(depth, -1);
+  depth[s] = 0;
+
+  while (!Q.empty()) {
+    int v = Q.front(); Q.pop();
+    
+    for (auto i : graph[v]) {
+      if (depth[i.u] == -1 && i.flow < i.cap) {
+        depth[i.u] = depth[v] + 1;
+        Q.push(i.u);
+      }
+    }
+  }
+
+  return depth[t] != -1;
+}
+
+
+int dfs(int s, int t, int flow) {
+  if (s == t)
+    return flow;
+
+  for ( ; start[s] < graph[s].size(); ++start[s]) {
+    edge &e = graph[s][start[s]];
+
+    if (depth[e.u] == depth[s] + 1 && e.flow < e.cap) {
+      int min_flow = dfs(e.u, t, min(flow, e.cap - e.flow));
+
+      if (min_flow > 0) {
+        e.flow += min_flow;
+        graph[e.u][e.rev].flow -= min_flow;
+        return min_flow;
+      }
+    }
+  }
+
+  return 0;
+}
+
+
+int dinic(int s, int t) {
+  int ans = 0;
+
+  while (bfs(s, t)) {
+    mset(start, 0);
+
+    while (int flow = dfs(s, t, inf))
+      ans += flow;
+  }
+
+  return ans;
+}
+
+
+int main() {
+  ios::sync_with_stdio(0);
+  cin.tie(0);
+
+  int p, r, c; cin >> p >> r >> c;
+  int s = 0, t = MAX - 1;
+  int dem = 0;
+
+  vector<int> dems(p);
+  for (auto &i : dems) {
+    cin >> i;
+    dem += i;
+  }
+
+  vector<int> ests(r);
+  for (auto &i : ests) cin >> i;
+
+  vector<pair<ii,int>> total;
+  for (int i = 0; i < c; ++i) {
+    int a, b, T; cin >> a >> b >> T;
+    total.pb(make_pair(ii(a, b), T));
+  }
+
+
+  int L = 0, R = 1010101;
+  for (int i = 0; i < 20; ++i) {
+    int m = (L + R) / 2;
+
+    for (int j = 0; j < p; ++j)
+      add_edge(j + 1 + r, t, dems[j]);
+
+    for (int j = 0; j < r; ++j)
+      add_edge(s, j + 1, ests[j]);
+
+    for (auto j : total) 
+      if (j.se <= m)
+        add_edge(j.fi.se, j.fi.fi + r, inf);
+
+    if (dinic(s, t) < dem)
+      L = m + 1;
+    else
+      R = m - 1;
+
+    for (int j = 0; j < MAX; ++j)
+      graph[j].clear();
+  }
+
+  cout << (L >= 1010101 ? -1 : L) << ende;
+  return 0;
+}
-- 
GitLab