Skip to content
Snippets Groups Projects
Commit 63373508 authored by Bruno Freitas Tissei's avatar Bruno Freitas Tissei
Browse files

Change formats

parent 810560ca
Branches
No related tags found
No related merge requests found
Showing
with 201 additions and 170 deletions
......@@ -7,16 +7,20 @@
typedef pair<double,double> dd;
// The three points are a counter-clockwise turn if cross > 0, clockwise if
// cross < 0, and collinear if cross = 0
/**
* The three points are a counter-clockwise turn if cross > 0, clockwise if
* cross < 0, and collinear if cross = 0
* @param a,b,c input points
*/
double cross(dd a, dd b, dd c) {
return (b.fi - a.fi) * (c.se - a.se) - (b.se - a.se) * (c.fi - a.fi);
}
// Find, among v, the points that form a convex hull
int convex_hull(vector<dd> &v) {
/**
* Finds, among v, the points that form a convex hull
* @param v vector of points
*/
int convex_hull(const vector<dd> &v) {
int k = 0;
vector<int> ans(v.sz * 2);
......@@ -47,6 +51,6 @@ int convex_hull(vector<dd> &v) {
sort(all(ans));
ans.erase(unique(all(ans)), ans.end());
// Returns amount of point in the convex hull
// Return number of points in the convex hull
return k - 1;
}
......@@ -16,8 +16,10 @@ vector<ii> bridges;
// Answer vector with articulations (vertices)
vector<int> articulations;
// Finds all articulations and bridges in the graph
/**
* Finds all articulations and bridges in the graph.
* @param x root vertex
*/
void dfs(int x) {
int child = 0;
cont[x] = 1;
......@@ -43,11 +45,13 @@ void dfs(int x) {
}
}
// Applies tarjan algorithm and format articulations vector
void tarjan(int v) {
/**
* Applies tarjan algorithm and format articulations vector.
* @param x root vertex
*/
void tarjan(int x) {
mset(parent, -1);
dfs(v);
dfs(x);
// Remove duplicates for articulations
sort(all(articulations));
......
......@@ -5,15 +5,17 @@
* Complexity (Space): O(V + E)
*/
struct edge {
int u, v, w;
};
struct edge { int u, v, w; };
int dist[MAX];
vector<edge> graph;
// Returns distance between s and d in a graph with V vertices
// using bellman_ford
/**
* Returns distance between s and d in a graph with V vertices
* using bellman_ford.
* @param s,d origin and destination vertices
* @param V number of vertices
*/
int bellman_ford(int s, int d, int V) {
mset(dist, inf);
dist[s] = 0;
......
......@@ -8,6 +8,10 @@
bool cont[MAX];
vector<int> graph[MAX];
/**
* Applies BFS on graph.
* @param x starting vertex
*/
void bfs(int x) {
queue<int> Q;
......
......@@ -8,7 +8,10 @@
vector<int> graph[MAX];
int cont[MAX], match[MAX];
// Find match for x
/**
* Finds match for x.
* @param x starting vertex
*/
int dfs(int x) {
if (cont[x])
return 0;
......@@ -23,14 +26,17 @@ int dfs(int x) {
return 0;
}
// Returns number of left elements in matching and fills match array with the
// match itself (match[right_i] = left_i)
/**
* Returns number of left elements in matching and fills match array with the
* match itself (match[right_i] = left_i).
* @param n number of vertices on the left
*/
int bipartite_matching(int n) {
int ans = 0;
memset(match, -1, sizeof match);
mset(match, -1);
for (int i = 0; i < n; ++i) {
memset(cont, 0, sizeof cont);
mset(cont, 0);
ans += dfs(i);
}
......
......@@ -8,6 +8,10 @@
bool cont[MAX];
vector<int> graph[MAX];
/**
* Applies DFS on graph.
* @param x starting vertex
*/
void dfs(int x) {
cont[x] = true;
for (auto i : graph[x])
......
......@@ -8,15 +8,18 @@
int dist[MAX];
vector<ii> graph[MAX];
// Get shortest distance from o to d
int dijkstra(int o, int d) {
/**
* Returns shortest distance from s to d
* @param s,d origin and destination vertices
*/
int dijkstra(int s, int d) {
set<ii> pq;
int u, v, wt;
mset(dist, inf);
dist[o] = 0;
pq.insert(ii(0, o));
dist[s] = 0;
pq.insert(ii(0, s));
while (pq.size() != 0) {
u = pq.begin()->second;
......@@ -26,7 +29,11 @@ int dijkstra(int o, int d) {
v = i.first;
wt = i.second;
// If the distance to v can be improved from d, improve it
if (dist[v] > dist[u] + wt) {
// Erase v from pq, because the distance was updated, if
// the distance is inf, then v is not on pq
if (dist[v] != inf)
pq.erase(pq.find(ii(dist[v], v)));
......
......@@ -6,7 +6,7 @@
*/
// Edge struct to be used in adjacency list similar to vector<ii> graph[MAX],
// but storing more information than ii
// but storing more information than ii.
struct edge {
int u;
int flow, cap;
......@@ -19,13 +19,15 @@ struct edge {
{}
};
int depth[MAX];
int start[MAX];
vector<edge> graph[MAX];
// Adds edge between s and t with capacity c
/**
* Adds edge to the graph.
* @param s,t origin and destination of edge
* @param c capacity of edge
*/
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());
......@@ -34,9 +36,11 @@ void add_edge(int s, int t, int c) {
graph[t].pb(backward);
}
// Calculates depth of each vertex from source, considering only
// edges with remaining capacity
/**
* Calculates depth of each vertex from source, considering only
* edges with remaining capacity.
* @param s,t source and sink of flow graph
*/
bool bfs(int s, int t) {
queue<int> Q;
Q.push(s);
......@@ -58,8 +62,11 @@ bool bfs(int s, int t) {
return depth[t] != -1;
}
// Finds bottleneck flow and add to the edges belonging to the paths found
/**
* Finds bottleneck flow and add to the edges belonging to the paths found.
* @param s,t source and sink of flow graph
* @param flow minimum flow so far
*/
int dfs(int s, int t, int flow) {
if (s == t)
return flow;
......@@ -84,8 +91,10 @@ int dfs(int s, int t, int flow) {
return 0;
}
// Returns maximum flow between s and t
/**
* Returns maximum flow.
* @param s,t source and sink of flow graph
*/
int dinic(int s, int t) {
int ans = 0;
......
......@@ -11,8 +11,11 @@ int graph[MAX][MAX], rg[MAX][MAX];
bool cont[MAX];
// Finds if there's a path between s and t using non-full
// residual edges
/**
* Finds if there's a path between s and t using non-full
* residual edges.
* @param s,t source and sink of flow graph
*/
bool bfs(int s, int t) {
queue<int> Q;
Q.push(s);
......@@ -21,6 +24,7 @@ bool bfs(int s, int t) {
while (!Q.empty()) {
int u = Q.front(); Q.pop();
// Sink was found, there is a path
if (u == t)
return true;
......@@ -35,8 +39,10 @@ bool bfs(int s, int t) {
return false;
}
// Returns maximum flow between s (source) and t (sink)
/**
* Returns maximum flow.
* @param s,t source and sink of flow graph
*/
int edmonds_karp(int s, int t) {
int ans = 0;
par[s] = -1;
......
......@@ -8,7 +8,10 @@
int dist[MAX][MAX];
int graph[MAX][MAX];
// Build dist matrix
/**
* Computes shortest path between all pairs of vertices.
* @param n number of vertices
*/
int floyd_warshall(int n) {
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
......@@ -17,6 +20,5 @@ int floyd_warshall(int n) {
for (int k = 0; k < n; ++k)
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
if (dist[i][k] + dist[k][j] < dist[i][j])
dist[i][j] = dist[i][k] + dist[k][j];
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])
}
......@@ -11,8 +11,11 @@ int graph[MAX][MAX], rg[MAX][MAX];
bool cont[MAX];
// Finds if there's a path between s and t using non-full
// residual edges
/**
* Finds if there's a path between s and t using non-full
* residual edges.
* @param s,t source and sink of flow graph
*/
bool dfs(int s, int t) {
cont[s] = true;
if (s == t)
......@@ -29,8 +32,10 @@ bool dfs(int s, int t) {
return false;
}
// Returns maximum flow between s (source) and t (sink)
/**
* Returns maximum flow.
* @param s,t source and sink of flow graph
*/
int ford_fulkerson(int s, int t) {
int ans = 0;
par[s] = -1;
......
......@@ -10,9 +10,12 @@ int matchL[MAX], matchR[MAX];
vector<int> graph[MAX];
// Builds an alternating level graph rooted at unmatched vertices in L
// using BFS, and returns whether there is an augmenting path in the graph
// or not
/**
* Builds an alternating level graph rooted at unmatched vertices in L
* using BFS, and returns whether there is an augmenting path in the graph
* or not.
* @param n number of vertices on the left
*/
bool bfs(int n) {
queue<int> Q;
......@@ -40,9 +43,11 @@ bool bfs(int n) {
return (dist[0] != inf);
}
// Augments path starting in l if there is one, returns
// whether a path was augmented or not
/**
* Augments path starting in l if there is one, returns
* whether a path was augmented or not.
* @param l initial free vertex on the left
*/
bool dfs(int l) {
if (l == 0)
return true;
......@@ -62,8 +67,10 @@ bool dfs(int l) {
return false;
}
// Returns number of matched vertices on the left (matched edges)
/**
* Returns number of matched vertices on the left (matched edges).
* @param n number of vertices on the left
*/
int hopcroft_karp(int n) {
mset(matchL, 0);
mset(matchR, 0);
......
......@@ -11,7 +11,10 @@ vector<int> transp[MAX];
bool cont[MAX];
// Traverse a SCC
/**
* Traverses a SCC.
* @param x initial vertex
*/
void dfs(int x) {
// x belong to current scc
cont[x] = true;
......@@ -21,8 +24,10 @@ void dfs(int x) {
dfs(i);
}
// Fill stack with DFS starting points to find SCC
/**
* Fills stack with DFS starting points to find SCC.
* @param x initial vertex
*/
void fill_stack(int x) {
cont[x] = true;
......@@ -33,12 +38,14 @@ void fill_stack(int x) {
S.push(x);
}
// Return number of SCC of a graph with n vertices
/**
* Returns number of SCC of a graph.
* @param n number of vertices
*/
int kosaraju(int n) {
int scc = 0;
memset(cont, 0, sizeof cont);
mset(cont, 0);
for (int i = 0; i < n; ++i)
if (!cont[i])
fill_stack(i);
......@@ -49,7 +56,7 @@ int kosaraju(int n) {
transp[j].push_back(i);
// Count SCC
memset(cont, 0, sizeof cont);
mset(cont, 0);
while (!S.empty()) {
int v = S.top();
S.pop();
......
......@@ -9,11 +9,16 @@
* OBS: * = return maximum spanning tree
*/
vector<iii> mst; // Result
typedef pair<ii,int> iii;
vector<iii> edges;
// Return value of MST and build mst vector with edges that belong to the tree
int kruskal() {
/**
* Returns value of MST.
* @param mst[out] vector with edges of computed MST
*/
int kruskal(vector<iii> &mst) {
// Sort by weight of the edges
sort(all(edges), [&](const iii &a, const iii &b) {
return a.se < b.se;
//* return a.se > b.se
......@@ -27,6 +32,7 @@ int kruskal() {
int pu = find_set(edges[i].fi.fi);
int pv = find_set(edges[i].fi.se);
// If the sets are different, then the edge i does not close a cycle
if (pu != pv) {
mst.pb(edges[i]);
size += edges[i].se;
......
......@@ -19,7 +19,10 @@ int h[MAX];
int par[MAX][MAXLOG];
//*** int cost[MAX][MAXLOG];
// Perform DFS while filling h, par, and cost
/**
* Performs DFS while filling h, par, and cost.
* @param v root of the tree
*/
void dfs(int v, int p = -1, int c = 0) {
par[v][0] = p;
//*** cost[v][0] = c;
......@@ -39,16 +42,20 @@ void dfs(int v, int p = -1, int c = 0) {
dfs(u.fi, v, u.se);
}
// Preprocess tree rooted at v
/**
* Preprocess tree.
* @param v root of the tree
*/
void preprocess(int v) {
mset(par, -1);
//*** mset(cost, 0;
dfs(v);
}
// Return LCA (or sum or max) between p and q
/**
* Returns LCA (or sum or max).
* @param p,q query nodes
*/
int query(int p, int q) {
//*** int ans = 0;
......@@ -73,11 +80,11 @@ int query(int p, int q) {
q = par[q][i];
}
return par[p][0];
//* if (p == q) return ans;
//* else return ans + cost[p][0] + cost[q][0];
//** if (p == q) return ans;
//** else return max(ans, max(cost[p][0], cost[q][0]));
return par[p][0];
}
......@@ -8,7 +8,9 @@
bool cont[MAX];
vector<ii> graph[MAX];
// Returns value of MST of graph
/**
* Returns value of MST of graph.
*/
int prim() {
mset(cont, false);
cont[0] = true;
......
......@@ -13,7 +13,10 @@ int ncomp, ind;
int cont[MAX], parent[MAX];
int low[MAX], L[MAX];
// Fills SCC with strongly connected components of graph
/**
* Fills SCC with strongly connected components of graph.
* @param x any vertex
*/
void dfs(int x) {
L[x] = ind;
low[x] = ind++;
......@@ -39,10 +42,12 @@ void dfs(int x) {
}
}
// Return number of SCCs
/**
* Return number of SCCs.
* @param n number of vertices
*/
int tarjan(int n) {
memset(L, -1, sizeof L);
mset(L, -1);
ncomp = ind = 0;
for (int i = 0; i < n; ++i)
......
......@@ -10,7 +10,10 @@ vector<int> graph[MAX];
int cont[MAX];
// Fill stack and check for cycles
/**
* Fills stack and check for cycles.
* @param x any vertex
*/
bool dfs(int x) {
cont[x] = 1;
......@@ -27,9 +30,11 @@ bool dfs(int x) {
return false;
}
// Returns whether graph contains cycle or not, and fills tsort vector with
// topological sort of the graph
/**
* Returns whether graph contains cycle or not.
* @param n number of vertices
* @param[out] tsort topological sort of the graph
*/
bool topological_sort(int n, vector<int> &tsort) {
mset(cont, 0);
......
/**
* Binary Exponentiation
*
* Complexity (Time): O(log n)
* Complexity (Space): O(1)
*/
/**
* Returns x^n in O(log n) time
* @param x number
* @param n exponent
*/
template <typename T>
T fast_pow(T x, ll n) {
T ans = 1;
while (n) {
if (n & 1)
ans = ans * x;
n >>= 1;
x = x * x;
}
return ans;
}
/**
* Fast Matrix Exponentiation
*
* Complexity (Time): O(K^3 log n)
* Complexity (Space): O(K^2)
*/
// This algorithm is used to solve recurrences such as:
// f(n) = x1 * f(n - 1) + x2 * f(n - 1) + ... + xk * f(n - k)
//
// It works by defining this recurrence as a linear combination,
// for example (k = 2):
// f(n) = [x1 x2] [f(n - 1)]
// [f(n - 2)]
// It can be rewriten as:
// [ f(n) ] = [x1 x2] [f(n - 1)]
// [f(n - 1)] [ 1 0] [f(n - 2)]
//
// And that is solved by calculating the following matrix power:
// [x1 x2]^n
// [ 1 0]
#define K 2
struct matrix {
ll m[K][K];
// Matrix multiplication - O(k^3)
matrix operator*(matrix a) {
matrix aux;
for (int i = 0; i < K; i++)
for (int j = 0; j < K; j++) {
ll sum = 0;
for (int k = 0; k < K; k++)
sum += (m[i][k] * a[k][j]) % MOD;
aux[i][j] = sum % MOD;
}
return aux;
}
ll *operator[](int i) {
return m[i];
}
void clear() {
mset(m, 0);
}
};
// Fast exponentiation (can be used with integers as well) - O(log n)
matrix matrix_pow(matrix in, ll n) {
matrix ans, b = in;
// Set ans as identity matrix
ans.clear();
for (int i = 0; i < K; ++i)
ans[i][i] = 1;
while (n) {
if (n & 1)
ans = ans * b;
n >>= 1;
b = b * b;
}
return ans;
}
// Solves f(n) = x * f(n - 1) + y * f(n - 2)
matrix solve(ll x, ll y, ll n) {
matrix in;
in[0][0] = x % MOD;
in[0][1] = y % MOD;
in[1][0] = 1;
in[1][1] = 0;
return matrix_pow(in, n);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment