diff --git a/algorithms/graph/dijkstra.cpp b/algorithms/graph/dijkstra.cpp index e80f124cc70939b1eefd946705071821199f1ef7..05cefc8c05a2e93e91f08a03aec3696a2a6b7768 100644 --- a/algorithms/graph/dijkstra.cpp +++ b/algorithms/graph/dijkstra.cpp @@ -1,5 +1,11 @@ /// Dijkstra /// +/// Description: +/// Dijkstra's algorithm for finding the shortest paths between nodes in a +/// graph. It works by greedily extending the shortest path at each step. \par +/// Doesn't work with negative-weighted edges, for that, Bellman-Ford +/// algorithm must be used. +/// /// Time: O(E + V log V) /// Space: O(V + E) @@ -18,7 +24,6 @@ struct Dijkstra { fill(all(dist), inf); } - // Returns shortest distance from s to d. int run(int s, int d) { set<ii> pq; diff --git a/algorithms/graph/dinic.cpp b/algorithms/graph/dinic.cpp index 0e96c6ee4b67ac4714da7233422210e6cda49652..fa3c52dbd27dd1aeb51e4ea5944a2f234c42c011 100644 --- a/algorithms/graph/dinic.cpp +++ b/algorithms/graph/dinic.cpp @@ -3,7 +3,7 @@ /// Time: O(E * V^2) /// Space: O(V + E) /// -/// Status: Tested (URI2882) +/// Status: Tested (URI2882,URI2354) struct Dinic { struct Edge { int u, f, c, r; }; @@ -16,8 +16,8 @@ struct Dinic { N(N), depth(N), start(N), graph(N) {} void add_edge(int s, int t, int c) { - Edge forw = { t, 0, c, graph[t].size() }; - Edge back = { s, 0, 0, graph[s].size() }; + Edge forw = { t, 0, c, (int) graph[t].size() }; + Edge back = { s, 0, 0, (int) graph[s].size() }; graph[s].pb(forw); graph[t].pb(back); diff --git a/algorithms/graph/edmonds_karp.cpp b/algorithms/graph/edmonds_karp.cpp index 61703a5fd3a283b7569f9bc953a4233e77da8be4..02eea4db659a41e77e47e42ac66c7fa4c0448a2b 100644 --- a/algorithms/graph/edmonds_karp.cpp +++ b/algorithms/graph/edmonds_karp.cpp @@ -2,6 +2,8 @@ /// /// Time: O(V * E^2) /// Space: O(V^2) +/// +/// Status: Tested (URI2354) int rg[MAX][MAX]; int graph[MAX][MAX]; diff --git a/algorithms/graph/ford_fulkerson.cpp b/algorithms/graph/ford_fulkerson.cpp index b04b1ca953a907123557667251c133b800664bd5..90fd2bb133a80acd914dabdf04911efe853f3a61 100644 --- a/algorithms/graph/ford_fulkerson.cpp +++ b/algorithms/graph/ford_fulkerson.cpp @@ -2,6 +2,8 @@ /// /// Time: O(E * f) /// Space: O(V^2) +/// +/// Status: Tested (URI2354) int rg[MAX][MAX]; int graph[MAX][MAX]; diff --git a/algorithms/graph/hopcroft_karp.cpp b/algorithms/graph/hopcroft_karp.cpp index b8abdceb193c3701da724cbf5800ef4f5178748d..78e2f89a4482d8f51206255f7ab419b7bf0fcc43 100644 --- a/algorithms/graph/hopcroft_karp.cpp +++ b/algorithms/graph/hopcroft_karp.cpp @@ -2,6 +2,10 @@ /// /// Time: O(E * sqrt{V}) /// Space: O(V + E) +/// +/// Status: Tested (GCJ18 - Round2 - B) +/// Caution: +/// - Assumes 1-indexed vertices in graph. vector<int> graph[MAX]; @@ -65,7 +69,7 @@ struct HopcroftKarp { int run() { int ans = 0; - while (bfs(L)) + while (bfs()) for (int l = 1; l <= L; ++l) if (matchL[l] == 0 && dfs(l)) ans++; diff --git a/algorithms/graph/kruskal.cpp b/algorithms/graph/kruskal.cpp index b657194cac1cf87e2d8e18e7cdb4f41820846cb3..6963eb263b8005016d1ff3b09ed4ba60e0eba4e5 100644 --- a/algorithms/graph/kruskal.cpp +++ b/algorithms/graph/kruskal.cpp @@ -1,6 +1,8 @@ /// Kruskal /// -/// Time: O (E log V) +/// +/// +/// Time: O(E log V) /// Space: O(E) /// /// Include: @@ -15,7 +17,8 @@ struct Kruskal { Kruskal(int N) : N(N), ds(N) {} - // Returns value of MST. + // Returns value of MST and fills mst vector with + // the edges from the MST. int run(vector<iii> &mst) { // Sort by weight of the edges diff --git a/algorithms/graph/lca.cpp b/algorithms/graph/lca.cpp index 9ea2aea626b27beb0d55c832ee1d6f14c53648a9..70d2ed37b2849bb1ec4e5a01ecbe0bf3830858b2 100644 --- a/algorithms/graph/lca.cpp +++ b/algorithms/graph/lca.cpp @@ -1,5 +1,17 @@ /// Lowest Common Ancestor (LCA) /// +/// Description: +/// The LCA between two nodes in a tree is a node that is an ancestor to both +/// nodes with the lowest height possible. \par +/// The algorithm works by following the path up the tree from both nodes +/// "simultaneously" until a common node is found. The naive approach for that +/// would be $O(n)$ in the worst case. To improve that, this implementation +/// uses "binary lifting" which is a way of figuring out the right number of +/// up-moves needed to find the LCA by following the binary representation of +/// the distance to the destination (similar to the "binary search by jumping"), +/// but, for that, a preprocessing must be done to set every parent at a $2^i$ +/// distance. +/// /// Time: /// - preprocess: O(V log V) /// - query: O(log V) diff --git a/algorithms/string/kmp.cpp b/algorithms/string/kmp.cpp index 48d2219648444e6a63baf176e936961bbe587932..91e38f5ef7b0a5b2cf366f87efc4f71776969f86 100644 --- a/algorithms/string/kmp.cpp +++ b/algorithms/string/kmp.cpp @@ -4,44 +4,37 @@ /// - preprocess: O(m) /// - search: O(n) /// Space: O(n + m) +/// +/// Status: Tested (URI2350) struct KMP { string patt; vector<int> table; KMP(string patt) : - patt(patt), table(patt.size()) + patt(patt), table(patt.size()+1) { preprocess(); } void preprocess() { - int i = 1, len = 0; + fill(all(table), -1); - while (i < patt.size()) { - if (patt[i] == patt[len]) - table[i++] = ++len; - else if (len) - len = table[len - 1]; - else - table[i++] = 0; + for (int i = 0, j = -1; i < patt.size(); ++i) { + while (j >= 0 && patt[i] != patt[j]) + j = table[j]; + table[i + 1] = ++j; } } vector<int> search(const string &txt) { - int i = 0, j = 0; vector<int> occurs; - while (i < txt.size()) { - if (patt[j] == txt[i]) - i++, j++; - + for (int i = 0, j = 0; i < txt.size(); ++i) { + while (j >= 0 && txt[i] != patt[j]) + j = table[j]; + j++; if (j == patt.size()) { - occurs.push_back(i - j); - j = table[j - 1]; - } else if (i < txt.size() && patt[j] != txt[i]) { - if (j > 0) - j = table[j - 1]; - else - i++; + occurs.pb(i - j); + j = table[j]; } } diff --git a/caderno.pdf b/caderno.pdf index 0b8ead1ae696fa179c417ea1e11169ea7900fd8a..1cae42f8e9135fa0a3d6179c538151d700127988 100644 Binary files a/caderno.pdf and b/caderno.pdf differ diff --git a/contests/CodeJam/2018/Round 2/A.cpp b/contests/CodeJam/2018/Round 2/A.cpp index 86fd46cd04fe69d54a34b0f9099100e36dbe3e31..3c2e56cee8d4515324ce81509931fe07013cc1fb 100644 --- a/contests/CodeJam/2018/Round 2/A.cpp +++ b/contests/CodeJam/2018/Round 2/A.cpp @@ -26,48 +26,39 @@ int main() { int t; cin >> t; for (int cas = 1; cas <= t; ++cas) { int c; cin >> c; - vector<int> v(c); - - int grt = 0; - for (auto &i : v) { - cin >> i; - grt = max(grt, i); + vector<int> v(c + 1); + int sum = 0; + for (int i = 1; i <= c; ++i) { + cin >> v[i]; + sum += v[i]; } cout << "Case #" << cas << ": "; - if (v[0] == 0 || v[c-1] == 0) { + if (v[1] == 0 || v[c] == 0 || sum != c) { cout << "IMPOSSIBLE" << ende; continue; } - vector<int> dest(c); - int l = 0, r = c - 1; - for (int i = 0; i < 1000; ++i) { - if (l >= r) break; - if (v[l] > 0) { - for (int i = 0; i < v[l]; ++i) - dest[l+i] = l; - l += v[l]; - } - - if (v[r] > 0) { - for (int i = 0; i < v[r]; ++i) - dest[r-i] = r; - r -= v[r]; - } - } - - - vector<string> ans(grt, string(c, '.')); + int k = 1; + vector<int> orig(c + 1); + for (int i = 1; i <= c; ++i) + for (int j = 0; j < v[i]; ++j) + orig[k++] = i; - vector<int> curr(c); + int grt = 0; + for (int i = 1; i <= c; ++i) + grt = max(grt, abs(orig[i] - i) + 1); + + vector<string> ans(grt, string(c + 1, '.')); + vector<int> curr(c + 1); iota(all(curr), 0); + for (int i = 0; i < grt; ++i) { - for (int j = 0; j < c; ++j) { - if (curr[j] > dest[j]) { + for (int j = 1; j <= c; ++j) { + if (curr[j] > orig[j]) { ans[i][curr[j]] = '/'; curr[j]--; - } else if (curr[j] < dest[j]) { + } else if (curr[j] < orig[j]) { ans[i][curr[j]] = '\\'; curr[j]++; } @@ -75,16 +66,20 @@ int main() { } bool poss = true; - for (int i = 0; i < c; ++i) - if (curr[i] != dest[i]) + for (int i = 1; i <= c; ++i) + if (curr[i] != orig[i]) poss = false; if (poss) { cout << grt << ende; - for (auto i : ans) - cout << i << ende; - } else + for (int i = 0; i < grt; ++i) { + for (int j = 1; j <= c; ++j) + cout << ans[i][j]; + cout << ende; + } + } else { cout << "IMPOSSIBLE" << ende; + } } return 0; diff --git a/contests/CodeJam/2018/Round 2/C.cpp b/contests/CodeJam/2018/Round 2/C.cpp new file mode 100644 index 0000000000000000000000000000000000000000..708257044ed51a868869c11ed901c84a0d38bc90 --- /dev/null +++ b/contests/CodeJam/2018/Round 2/C.cpp @@ -0,0 +1,127 @@ +#include <bits/stdc++.h> + +#define MAX 221 +#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; + +using ll = long long; +using ii = pair<int,int>; + +vector<int> graph[MAX]; + +struct HopcroftKarp { + int L, R; + vector<int> dist; + vector<int> matchL, matchR; + + HopcroftKarp(int L, int R) : + L(L), R(R), dist(L), + matchL(L), matchR(R) + { init(); } + + void init() { + fill(all(matchL), 0); + fill(all(matchR), 0); + } + + bool bfs() { + queue<int> Q; + + for (int l = 1; l <= L; ++l) + if (matchL[l] == 0) { + dist[l] = 0; + Q.push(l); + } else { + dist[l] = inf; + } + + dist[0] = inf; + while (!Q.empty()) { + int l = Q.front(); Q.pop(); + + if (dist[l] < dist[0]) + for (auto r : graph[l]) + if (dist[matchR[r]] == inf) { + dist[matchR[r]] = dist[l] + 1; + Q.push(matchR[r]); + } + } + + return (dist[0] != inf); + } + + bool dfs(int l) { + if (l == 0) + return true; + + for (auto r : graph[l]) + if (dist[matchR[r]] == dist[l] + 1) + if (dfs(matchR[r])) { + matchR[r] = l; + matchL[l] = r; + return true; + } + + dist[l] = inf; + return false; + } + + int run() { + int ans = 0; + + while (bfs()) + for (int l = 1; l <= L; ++l) + if (matchL[l] == 0 && dfs(l)) + ans++; + + return ans; + } +}; + +int main() { + ios::sync_with_stdio(0); + cin.tie(0); + + int t; cin >> t; + for (int cas = 1; cas <= t; ++cas) { + int n; cin >> n; + vector<vector<int>> mat(n, vector<int>(n)); + for (auto &i : mat) + for (auto &j : i) + cin >> j; + + cout << "Case #" << cas << ": "; + int ans = 0; + for (int i = -n; i <= n; ++i) { + for (int j = 0; j < MAX; ++j) + graph[j].clear(); + + int num = 0; + for (int j = 0; j < n; ++j) + for (int k = 0; k < n; ++k) + if (mat[j][k] == i) { + num++; + graph[j + 1].pb(n + k + 1); + } + + HopcroftKarp hk(n+n+1, n+n+1); + ans += (num - hk.run()); + } + cout << ans << ende; + } + + return 0; +} diff --git a/contests/ICPC_LA16/A.cpp b/contests/ICPC_LA16/A.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eb471d2be6ff3758b15f4279b8dc8eefbf346e08 --- /dev/null +++ b/contests/ICPC_LA16/A.cpp @@ -0,0 +1,32 @@ +#include <bits/stdc++.h> + +#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; + +using ll = long long; +using ii = pair<int,int>; + +int main() { + ios::sync_with_stdio(0); + cin.tie(0); + + vector<int> v(4); + for (auto &i : v) cin >> i; + sort(all(v)); + + cout << abs((v[0] + v[3]) - (v[1] + v[2])) << ende; + return 0; +} diff --git a/contests/ICPC_LA16/B.cpp b/contests/ICPC_LA16/B.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e7d2f6bd6c8299a774490ab5af0f62c7b5e11f8c --- /dev/null +++ b/contests/ICPC_LA16/B.cpp @@ -0,0 +1,72 @@ +#include <bits/stdc++.h> + +#define MAX 101010 +#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; + +using ll = long long; +using ii = pair<int,int>; + +set<int> graph[MAX]; + +int main() { + ios::sync_with_stdio(0); + cin.tie(0); + + int n, m, a, b; cin >> n >> m >> a >> b; + for (int i = 0; i < m; ++i) { + int x, y; cin >> x >> y; + graph[x].insert(y); + graph[y].insert(x); + } + + set<ii> S; + for (int i = 1; i <= n; ++i) + S.insert(ii(graph[i].size(), i)); + + bool ended = false; + while (!ended) { + ended = true; + while (S.size() && S.begin()->fi < a) { + ii u = *(S.begin()); S.erase(S.begin()); + + for (auto i : graph[u.se]) { + S.erase(ii(graph[i].size(), i)); + graph[i].erase(u.se); + S.insert(ii(graph[i].size(), i)); + } + + graph[u.se].clear(); + ended = false; + } + + while (S.size() && S.size() - prev(S.end())->fi - 1 < b) { + ii u = *(prev(S.end())); S.erase(prev(S.end())); + + for (auto i : graph[u.se]) { + S.erase(ii(graph[i].size(), i)); + graph[i].erase(u.se); + S.insert(ii(graph[i].size(), i)); + } + + graph[u.se].clear(); + ended = false; + } + } + + cout << S.size() << ende; + return 0; +} diff --git a/contests/ICPC_LA16/D.cpp b/contests/ICPC_LA16/D.cpp new file mode 100644 index 0000000000000000000000000000000000000000..46f69ec9705ea5f0456454bcfcf7e64615a014b9 --- /dev/null +++ b/contests/ICPC_LA16/D.cpp @@ -0,0 +1,53 @@ +#include <bits/stdc++.h> + +#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)) + +#define to_rad(x) (x * M_PI) / 180.0 + +using namespace std; + +using ll = long long; +using ii = pair<int,int>; +using dd = pair<double,double>; + +int main() { + ios::sync_with_stdio(0); + cin.tie(0); + cout << setprecision(3) << fixed; + + int n; cin >> n; + vector<int> v(n); + for (auto &i : v) cin >> i; + sort(all(v)); + + vector<int> u(n); + int a = 0, b = n - 1; + for (int i = 0; i < n; ++i) { + if (i % 2) u[b--] = v[i]; + else u[a++] = v[i]; + } + + vector<dd> points(n); + for (int i = 0; i < n; ++i) { + points[i].fi = u[i] * cos(to_rad((360.0 / n) * (i + 1))); + points[i].se = u[i] * sin(to_rad((360.0 / n) * (i + 1))); + } + + double sum = 0.0; + for (int i = 0; i < n; ++i) + sum += points[i].fi * points[(i+1) % n].se - points[i].se * points[(i+1)%n].fi; + cout << sum / 2.0 << ende; + return 0; +} diff --git a/contests/ICPC_LA16/F.cpp b/contests/ICPC_LA16/F.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8d1ea908689fd6b99a67e8e9dde8c10740629e4f --- /dev/null +++ b/contests/ICPC_LA16/F.cpp @@ -0,0 +1,37 @@ +#include <bits/stdc++.h> + +#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; + +using ll = long long; +using ii = pair<int,int>; + +int main() { + ios::sync_with_stdio(0); + cin.tie(0); + + int n, c, s; cin >> n >> c >> s; s--; + int curr = 0, ans = curr == s; + for (int i = 0; i < c; ++i) { + int x; cin >> x; + curr = ((curr + x) + n) % n; + if (curr == s) + ans++; + } + + cout << ans << ende; + return 0; +} diff --git a/contests/ICPC_LA16/G.cpp b/contests/ICPC_LA16/G.cpp new file mode 100644 index 0000000000000000000000000000000000000000..67c7bb3e9efc863a10167b0e91f1e8387eded30e --- /dev/null +++ b/contests/ICPC_LA16/G.cpp @@ -0,0 +1,85 @@ +#include <bits/stdc++.h> + +#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; + +using ll = long long; +using ii = pair<int,int>; + +struct KMP { + vector<int> patt; + vector<int> table; + + KMP(vector<int> patt) : + patt(patt), table(patt.size()+1) + { preprocess(); } + + void preprocess() { + fill(all(table), -1); + + for (int i = 0, j = -1; i < patt.size(); ++i) { + while (j >= 0 && patt[i] != patt[j] && (patt[j] || patt[i] <= j)) + j = table[j]; + table[i + 1] = ++j; + } + } + + int search(const vector<int> &txt) { + int ans = 0; + for (int i = 0, j = 0; i < txt.size(); ++i) { + while (j >= 0 && txt[i] != patt[j] && (patt[j] || txt[i] <= j)) + j = table[j]; + ++j; + if (j == patt.size()) { + ans++; + j = table[j]; + } + } + + return ans; + } +}; + +int main() { + ios::sync_with_stdio(0); + cin.tie(0); + + string s; cin >> s; + int n; cin >> n; + vector<int> v(n); + for (auto &i : v) { + cin >> i; --i; + } + + vector<int> last(30, -1); + vector<int> A(s.size()), B(n); + for (int i = 0; i < s.size(); ++i) { + if (last[s[i] - 'a'] == -1) A[i] = 0; + else A[i] = i - last[s[i] - 'a']; + last[s[i] - 'a'] = i; + } + + fill(all(last), -1); + for (int i = 0; i < v.size(); ++i) { + if (last[v[i]] == -1) B[i] = 0; + else B[i] = i - last[v[i]]; + last[v[i]] = i; + } + + KMP kmp(B); + cout << kmp.search(A) << ende; + return 0; +} diff --git a/contests/ICPC_LA16/J.cpp b/contests/ICPC_LA16/J.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b6794af1284533afd1ec9e065942bae2cd28877e --- /dev/null +++ b/contests/ICPC_LA16/J.cpp @@ -0,0 +1,42 @@ +#include <bits/stdc++.h> + +#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; + +using ll = long long; +using ii = pair<int,int>; + +int main() { + ios::sync_with_stdio(0); + cin.tie(0); + + int n; cin >> n; + if (n == 2) return cout << 2 << ende, 0; + for (int i = n; i >= 0; --i) { + if (i % 2 == 0) continue; + bool done = true; + for (int j = 3; j * j <= n; j += 2) + if (i % j == 0) { + done = false; + break; + } + + if (done) + return cout << i << ende, 0; + } + + return 0; +} diff --git a/contests/ICPC_LA16/K.cpp b/contests/ICPC_LA16/K.cpp new file mode 100644 index 0000000000000000000000000000000000000000..96356ddf0604c5ed403b8f8da6e91315d26521f7 --- /dev/null +++ b/contests/ICPC_LA16/K.cpp @@ -0,0 +1,136 @@ +#include <bits/stdc++.h> + +#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; + +using ll = long long; +using ii = pair<int,int>; + +struct Dinic { + struct Edge { int u, f, c, r; }; + + int N; + vector<int> depth, start; + vector<vector<Edge>> graph; + + Dinic(int N) : + N(N), depth(N), start(N), graph(N) {} + + void add_edge(int s, int t, int c) { + Edge forw = { t, 0, c, (int) graph[t].size() }; + Edge back = { s, 0, 0, (int) graph[s].size() }; + + graph[s].pb(forw); + graph[t].pb(back); + } + + bool bfs(int s, int t) { + queue<int> Q; + Q.push(s); + + fill(all(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.f < i.c) { + depth[i.u] = depth[v] + 1; + Q.push(i.u); + } + } + + return depth[t] != -1; + } + + int dfs(int s, int t, int f) { + if (s == t) + return f; + + for ( ; start[s] < graph[s].size(); ++start[s]) { + Edge &e = graph[s][start[s]]; + + if (depth[e.u] == depth[s] + 1 && e.f < e.c) { + int min_f = dfs(e.u, t, min(f, e.c - e.f)); + + if (min_f > 0) { + e.f += min_f; + graph[e.u][e.r].f -= min_f; + return min_f; + } + } + } + + return 0; + } + + int run(int s, int t) { + int ans = 0; + while (bfs(s, t)) { + fill(all(start), 0); + + while (int flow = dfs(s, t, inf)) + ans += flow; + } + + return ans; + } +}; + +int main() { + ios::sync_with_stdio(0); + cin.tie(0); + + int n; cin >> n; + vector<ii> v(n+1); + for (int i = 1; i <= n; ++i) + cin >> v[i].fi >> v[i].se; + + int ans = 0; + for (int i = 1; i <= n; ++i) { + int votes = 0, pass = 0; + int s = 0, t = 2*n + 1; + Dinic dinic(t + 1); + + for (int j = 1; j <= n; ++j) { + if (i == j) + continue; + + if (v[j].fi == i || v[j].se == i) { + votes++; + continue; + } + + dinic.add_edge(s, j, 1); + dinic.add_edge(j, v[j].fi + n, 1); + dinic.add_edge(j, v[j].se + n, 1); + pass++; + } + + for (int j = 1; j <= n; ++j) + if (v[i].fi == j || v[i].se == j) + dinic.add_edge(j + n, t, votes - 2); + else + dinic.add_edge(j + n, t, votes - 1); + + if (dinic.run(s, t) < pass) + ans++; + } + + cout << ans << ende; + return 0; +} diff --git a/notebook/gen_latex.py b/notebook/gen_latex.py index 76eee468bb98a4d2461bd6897b02525ea58d0095..4871f39d0754c646f75765d1c458260d8533fe6c 100644 --- a/notebook/gen_latex.py +++ b/notebook/gen_latex.py @@ -49,7 +49,7 @@ class LatexGenerator: self.header = {} self.code, self.raw_header = [], [] self.sections = ['Description', 'Time', 'Space', 'Include', - 'Status'] + 'Status', 'Caution'] self._parse_source(source) self._parse_header()