Merge branch 'master' of https://github.com/thecodingwizard/usaco-training-2.0
This commit is contained in:
commit
6db2450f06
4 changed files with 112 additions and 48 deletions
|
@ -1,32 +1,35 @@
|
||||||
# Silver - Graphs
|
# Silver - DFS
|
||||||
|
|
||||||
Author: Siyong Huang
|
Author: Siyong Huang
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
- Prerequisites
|
- Prerequisites
|
||||||
- Depth First Search (DFS)
|
- Depth First Search (DFS)
|
||||||
- Flood Fill
|
- Flood Fill
|
||||||
- Graph Two-Coloring
|
- Graph Two-Coloring
|
||||||
- Cycle Detection
|
- Cycle Detection
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
- [Graph Theory](https://csacademy.com/lesson/introduction_to_graphs)
|
- [CSAcademy Graph Theory](https://csacademy.com/lesson/introduction_to_graphs)
|
||||||
- [Graph Representations](https://csacademy.com/lesson/graph_representation)
|
- [CSAcademy Graph Representations](https://csacademy.com/lesson/graph_representation)
|
||||||
- Note: DFS is most commonly implemented with adjacency lists
|
- Note: DFS is most commonly implemented with adjacency lists.
|
||||||
|
|
||||||
## Depth First Search (DFS)
|
## Depth First Search (DFS)
|
||||||
|
|
||||||
*Depth First Search*, more commonly DFS, is a fundamental graph algorithm that traverses an entire connected component. The rest of this document describe various applications of DFS.
|
*Depth First Search*, more commonly DFS, is a fundamental graph algorithm that traverses an entire connected component. The rest of this document describes various applications of DFS. Of course, it is one possible way to implement flood fill. *Breadth first search* (BFS) is **not** required for silver.
|
||||||
|
|
||||||
|
- [CSES Building Roads](https://cses.fi/problemset/task/1666)
|
||||||
|
|
||||||
### Tutorial
|
### Tutorial
|
||||||
|
|
||||||
- Recommended:
|
- Recommended:
|
||||||
- [CSAcademy BFS](https://csacademy.com/lesson/depth_first_search/)
|
- [CSAcademy DFS](https://csacademy.com/lesson/depth_first_search/)
|
||||||
- Additional:
|
- Additional:
|
||||||
- CPH Chapter 12
|
- CPH Chapter 12
|
||||||
- [cp-algo DFS](https://cp-algorithms.com/graph/depth-first-search.html)
|
- [cp-algo DFS](https://cp-algorithms.com/graph/depth-first-search.html)
|
||||||
|
- hard to parse if this is your first time learning about DFS
|
||||||
|
|
||||||
### Problems
|
### Problems
|
||||||
|
|
||||||
|
@ -38,7 +41,10 @@ Author: Siyong Huang
|
||||||
|
|
||||||
## Flood Fill
|
## Flood Fill
|
||||||
|
|
||||||
*Flood Fill* refers to finding the number of connected components in a graph, frequently on a grid.
|
*Flood Fill* refers to finding the number of connected components in a graph, usually when the graph is a grid.
|
||||||
|
|
||||||
|
- [CSES Counting Rooms](https://cses.fi/problemset/task/1192)
|
||||||
|
- [CSES Labyrinth](https://cses.fi/problemset/task/1193)
|
||||||
|
|
||||||
### Tutorial
|
### Tutorial
|
||||||
|
|
||||||
|
@ -56,13 +62,17 @@ Author: Siyong Huang
|
||||||
## Graph Two-Coloring
|
## Graph Two-Coloring
|
||||||
|
|
||||||
*Graph two-colorings* is assigning a boolean value to each node of the graph, dictated by the edge configuration
|
*Graph two-colorings* is assigning a boolean value to each node of the graph, dictated by the edge configuration
|
||||||
The most common example of a two-colored graph is a *bipartite graph*, in which each edge connects two nodes of opposite colors
|
The most common example of a two-colored graph is a *bipartite graph*, in which each edge connects two nodes of opposite colors.
|
||||||
|
|
||||||
|
- [CSES Building Teams](https://cses.fi/problemset/task/1668)
|
||||||
|
|
||||||
### Tutorial
|
### Tutorial
|
||||||
|
|
||||||
The idea is that we can arbitrarily label a node and then run DFS. Every time we visit a new (unvisited) node, we set its color based on the edge rule. When we visit a previously visited node, check to see whether its color matches the edge rule. For example, an implementation of coloring a bipartite graph is shown below.
|
The idea is that we can arbitrarily label a node and then run DFS. Every time we visit a new (unvisited) node, we set its color based on the edge rule. When we visit a previously visited node, check to see whether its color matches the edge rule. For example, an implementation of coloring a bipartite graph is shown below.
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
|
//UNTESTED
|
||||||
|
|
||||||
bool is_bipartite = true;
|
bool is_bipartite = true;
|
||||||
void dfs(int node)
|
void dfs(int node)
|
||||||
{
|
{
|
||||||
|
@ -83,7 +93,7 @@ void dfs(int node)
|
||||||
|
|
||||||
- Additional:
|
- Additional:
|
||||||
- [Bipartite Graphs: cp-alg bipartite check](https://cp-algorithms.com/graph/bipartite-check.html)
|
- [Bipartite Graphs: cp-alg bipartite check](https://cp-algorithms.com/graph/bipartite-check.html)
|
||||||
- Note: CP Algorithm uses bfs, but dfs accomplishes the same task
|
- Note: CP-Algorithms uses BFS, but DFS accomplishes the same task
|
||||||
|
|
||||||
### Problems
|
### Problems
|
||||||
|
|
||||||
|
@ -91,18 +101,28 @@ void dfs(int node)
|
||||||
|
|
||||||
## Cycle Detection
|
## Cycle Detection
|
||||||
|
|
||||||
A *cycle* is a non-empty path of distinct edges that start and end at the same node.
|
A *cycle* is a non-empty path of distinct edges that start and end at the same node. *Cycle detection* determines properties of cycles in a directed or undirected graph, such as whether each node of the graph is part of a cycle or just checking whether a cycle exists.
|
||||||
*Cycle detection* determines properties of cycles in a graph, such as counting the number of cycles in a graph or determining whether a node is in a cycle. For most silver-level cycle problems, each node has only one out-degree, meaning that it's adjacency list is of size 1. If this is not the case, the problem generalizes to *Strongly Connected Components*, a platinum level concept.
|
|
||||||
|
|
||||||
### Tutorial
|
A related topic is **strongly connected components**, a platinum level concept.
|
||||||
|
|
||||||
The following sample code counts the number of cycles in a graph where each node points to one other node. The "stack" contains nodes that can reach the current node. If the current node points to a node v on the stack (on_stack[v] is true), then we know that a cycle has been created. However, if the current node points to a node v that has been previously visited but is not on the stack, then we know that the current chain of nodes points into a cycle that has already been considered.
|
### Functional Graphs
|
||||||
|
|
||||||
|
Links:
|
||||||
|
|
||||||
|
* CPH 16.3: successor paths
|
||||||
|
* CPH 16.4: cycle detection in successor graph
|
||||||
|
|
||||||
|
In silver-level directed cycle problems, it is generally the case that each node has exactly one edge going out of it. This is known as a **successor graph** or a **functional graph.**
|
||||||
|
|
||||||
|
The following sample code counts the number of cycles in such a graph. The "stack" contains nodes that can reach the current node. If the current node points to a node `v` on the stack (`on_stack[v]` is true), then we know that a cycle has been created. However, if the current node points to a node `v` that has been previously visited but is not on the stack, then we know that the current chain of nodes points into a cycle that has already been considered.
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
|
//UNTESTED
|
||||||
|
|
||||||
//Each node points to next_node[node]
|
//Each node points to next_node[node]
|
||||||
|
|
||||||
bool visited[MAXN], on_stack[MAXN];
|
bool visited[MAXN], on_stack[MAXN];
|
||||||
int number_of_cycles = 0;
|
int number_of_cycles = 0, next_node[MAXN];
|
||||||
void dfs(int n)
|
void dfs(int n)
|
||||||
{
|
{
|
||||||
visited[n] = on_stack[n] = true;
|
visited[n] = on_stack[n] = true;
|
||||||
|
@ -122,10 +142,58 @@ int main()
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The same general idea is implemented below to find any cycle in a directed graph (if one exists).
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
//UNTESTED
|
||||||
|
|
||||||
|
bool visited[MAXN], on_stack[MAXN];
|
||||||
|
vector<int> adj[MAXN];
|
||||||
|
vector<int> cycle;
|
||||||
|
bool dfs(int n)
|
||||||
|
{
|
||||||
|
visited[n] = on_stack[n] = true;
|
||||||
|
for(int u:adj[n])
|
||||||
|
{
|
||||||
|
if(on_stack[u])
|
||||||
|
return cycle.push_back(v), cycle.push_back(u), on_stack[n] = on_stack[u] = false, true;
|
||||||
|
else if(!visited[u])
|
||||||
|
{
|
||||||
|
if(dfs(u))
|
||||||
|
if(on_stack[n])
|
||||||
|
return cycle.push_back(n), on_stack[n] = false, true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
if(!cycle.empty())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
on_stack[n] = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
//take input, etc
|
||||||
|
for(int i = 1;cycle.empty() && i <= N;i++)
|
||||||
|
dfs(i);
|
||||||
|
if(cycle.empty())
|
||||||
|
printf("No cycle found!\n");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reverse(cycle.begin(), cycle.end());
|
||||||
|
printf("Cycle of length %u found!\n", cycle.size());
|
||||||
|
for(int n : cycle) printf("%d ", n);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Problems
|
### Problems
|
||||||
|
|
||||||
- [Codeforces 1020B. Badge (Very Easy)](https://codeforces.com/contest/1020/problem/B)
|
- [Codeforces 1020B. Badge (Very Easy)](https://codeforces.com/contest/1020/problem/B)
|
||||||
- Try to solve the problem in O(N)!
|
- Try to solve the problem in O(N)!
|
||||||
- [The Bovine Shuffle (Normal)](http://usaco.org/index.php?page=viewproblem2&cpid=764)
|
- [The Bovine Shuffle (Normal)](http://usaco.org/index.php?page=viewproblem2&cpid=764)
|
||||||
- [Swapity Swapity Swap (Very Hard)](http://www.usaco.org/index.php?page=viewproblem2&cpid=1014)
|
- [Swapity Swapity Swap (Very Hard)](http://www.usaco.org/index.php?page=viewproblem2&cpid=1014)
|
||||||
|
- [CSES Round Trip (undirected)](https://cses.fi/problemset/task/1669)
|
||||||
|
- [CSES Round Trip II (directed)](https://cses.fi/problemset/task/1678)
|
||||||
|
|
||||||
|
|
|
@ -70,5 +70,6 @@ Hasn't appeared in recent USACO Gold as far as I know.
|
||||||
|
|
||||||
* [CSES High Score](https://cses.fi/problemset/task/1673)
|
* [CSES High Score](https://cses.fi/problemset/task/1673)
|
||||||
* [Kattis SSSP Negative](https://open.kattis.com/problems/shortestpath3)
|
* [Kattis SSSP Negative](https://open.kattis.com/problems/shortestpath3)
|
||||||
|
* [CSES Cycle Finding](https://cses.fi/problemset/task/1197)
|
||||||
|
|
||||||
Can also modify Dijkstra's so it works with negative edge weights (but not negative cycles). The same running time bound no longer applies.
|
Can also modify Dijkstra's so it works with negative edge weights (but not negative cycles). The same running time bound no longer applies.
|
||||||
|
|
|
@ -16,7 +16,7 @@ From the latter link (modified):
|
||||||
> * It can be divided into multiple sections, where each section is a linear function (usually) with an integer slope.
|
> * It can be divided into multiple sections, where each section is a linear function (usually) with an integer slope.
|
||||||
> * It is a convex/concave function. In other words, the slope of each section is non-decreasing or non-increasing when scanning the function from left to right.
|
> * It is a convex/concave function. In other words, the slope of each section is non-decreasing or non-increasing when scanning the function from left to right.
|
||||||
|
|
||||||
It's generally applicable as a DP optimization.
|
It's generally applicable as a DP optimization. Usually you can come up with a slower DP (ex. $O(N^2)$) first and then optimize it to $O(N\log N)$ with slope trick.
|
||||||
|
|
||||||
This document assumes some familiarity with at least one of the links above.
|
This document assumes some familiarity with at least one of the links above.
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ This document assumes some familiarity with at least one of the links above.
|
||||||
|
|
||||||
[CF Buy Low Sell High](https://codeforces.com/contest/866/problem/D)
|
[CF Buy Low Sell High](https://codeforces.com/contest/866/problem/D)
|
||||||
|
|
||||||
Let $dp[i][j]$ denote the maximum amount of money you can have on day $i$ if you have exactly $j$ shares of stock on that day. The final answer will be $dp[N][0]$. This easily leads to an $O(N^2)$ DP.
|
**Slow Solution**: Let $dp[i][j]$ denote the maximum amount of money you can have on day $i$ if you have exactly $j$ shares of stock on that day. The final answer will be $dp[N][0]$. This easily leads to an $O(N^2)$ DP.
|
||||||
|
|
||||||
Of course, we never used the fact that the DP is concave down! Specifically, let $dif[i][j]=dp[i][j]-dp[i][j+1]\ge 0$. Then $dif[i][j]\le dif[i][j+1]$ for all $j\ge 0$ (ignoring the case when we get $dp$ values of $-\infty$).
|
Of course, we never used the fact that the DP is concave down! Specifically, let $dif[i][j]=dp[i][j]-dp[i][j+1]\ge 0$. Then $dif[i][j]\le dif[i][j+1]$ for all $j\ge 0$ (ignoring the case when we get $dp$ values of $-\infty$).
|
||||||
|
|
||||||
|
@ -69,9 +69,9 @@ int main() {
|
||||||
|
|
||||||
Let $dif_i=a_i-b_i$. Defining $d_j=\sum_{i=1}^jdif_i$, our goal is to move around the potatoes such that $d_0,d_1,\ldots,d_N$ is a non-decreasing sequence. Moving a potato is equivalent to changing exactly one of the $d_i$ (aside from $d_0,d_N$) by one.
|
Let $dif_i=a_i-b_i$. Defining $d_j=\sum_{i=1}^jdif_i$, our goal is to move around the potatoes such that $d_0,d_1,\ldots,d_N$ is a non-decreasing sequence. Moving a potato is equivalent to changing exactly one of the $d_i$ (aside from $d_0,d_N$) by one.
|
||||||
|
|
||||||
As before, we can come up with a $O(N\cdot d_N)$ solution, where $dp[i][j]$ is the minimum cost to determine $d_0,d_1,\ldots,d_i$ such that $d_i\le j$. As before, this DP is concave up for a fixed $i$!!
|
**Slow Solution:** Let $dp[i][j]$ be the minimum cost to determine $d_0,d_1,\ldots,d_i$ such that $d_i\le j$ for each $0\le j\le d_N$. This gives a $O(N\cdot d_N)$ solution.
|
||||||
|
|
||||||
So given a piecewise linear function $DP_x$, we need to support the following operations.
|
As before, this DP is concave up for a fixed $i$! Given a piecewise linear function $DP_x$, we need to support the following operations.
|
||||||
|
|
||||||
* Add $|x-k|$ to the function for some $k$
|
* Add $|x-k|$ to the function for some $k$
|
||||||
* Set $DP_x=\min(DP_x,DP_{x-1})$ for all $x$
|
* Set $DP_x=\min(DP_x,DP_{x-1})$ for all $x$
|
||||||
|
@ -181,11 +181,11 @@ int main() {
|
||||||
|
|
||||||
## Problems
|
## Problems
|
||||||
|
|
||||||
|
* [Moving Haybales (USACO Camp)](https://probgate.org/viewproblem.php?pid=247)
|
||||||
* [Wall](https://atcoder.jp/contests/kupc2016/tasks/kupc2016_h)
|
* [Wall](https://atcoder.jp/contests/kupc2016/tasks/kupc2016_h)
|
||||||
* same as potatoes
|
* same as "Potatoes"
|
||||||
* [Stock Trading](https://probgate.org/viewproblem.php?pid=531&cid=81)
|
* [Stock Trading (USACO Camp)](https://probgate.org/viewproblem.php?pid=531&cid=81)
|
||||||
* extension of buy low sell high
|
* extension of "Buy Low Sell High"
|
||||||
* USACO Camp (private)
|
|
||||||
* [Bookface](https://codeforces.com/group/ZFgXbZSjvp/contest/274852/problem/C)
|
* [Bookface](https://codeforces.com/group/ZFgXbZSjvp/contest/274852/problem/C)
|
||||||
* [CCDSAP Exam](https://www.codechef.com/problems/CCDSAP)
|
* [CCDSAP Exam](https://www.codechef.com/problems/CCDSAP)
|
||||||
* [Farm of Monsters](https://codeforces.com/gym/102538/problem/F)
|
* [Farm of Monsters](https://codeforces.com/gym/102538/problem/F)
|
||||||
|
|
|
@ -37,46 +37,41 @@
|
||||||
- Standard Containers
|
- Standard Containers
|
||||||
- ex. [Convention II](http://usaco.org/index.php?page=viewproblem2&cpid=859)
|
- ex. [Convention II](http://usaco.org/index.php?page=viewproblem2&cpid=859)
|
||||||
- Sorting
|
- Sorting
|
||||||
- Binary Search (BinSearch)
|
- ex. [Counting Haybales](http://usaco.org/index.php?page=viewproblem2&cpid=666)
|
||||||
- ex. [Counting Haybales](http://usaco.org/index.php?page=viewproblem2&cpid=666)
|
- Binary Search (BinSearch)
|
||||||
|
- ex. [Convention](http://usaco.org/index.php?page=viewproblem2&cpid=858)
|
||||||
- Two Pointers (2P)
|
- Two Pointers (2P)
|
||||||
- ex. [Diamond Collector](http://usaco.org/index.php?page=viewproblem2&cpid=643)
|
- ex. [Diamond Collector](http://usaco.org/index.php?page=viewproblem2&cpid=643)
|
||||||
- Prefix Sums (Psum)
|
- Prefix Sums (Psum)
|
||||||
- ex. [Breed Counting](http://www.usaco.org/index.php?page=viewproblem2&cpid=572)
|
- ex. [Breed Counting](http://www.usaco.org/index.php?page=viewproblem2&cpid=572)
|
||||||
- Flood Fill (FF)
|
- DFS
|
||||||
- ex. [Switching on the Lights](http://www.usaco.org/index.php?page=viewproblem2&cpid=570)
|
- ex. [Switching on the Lights](http://www.usaco.org/index.php?page=viewproblem2&cpid=570)
|
||||||
- Occasionally, graph problems appear in bronze ...
|
- Occasionally, graph problems appear in bronze ...
|
||||||
- Permutations
|
|
||||||
- Cycle Decomposition?
|
|
||||||
- ex. [Swapity Swapity Swap](http://www.usaco.org/index.php?page=viewproblem2&cpid=1014)
|
|
||||||
|
|
||||||
# Gold
|
# Gold
|
||||||
|
|
||||||
- Dynamic Programming (DP)
|
- Dynamic Programming (DP)
|
||||||
- ex. [Time is Mooney](http://www.usaco.org/index.php?page=viewproblem2&cpid=993)
|
- ex. [Time is Mooney](http://www.usaco.org/index.php?page=viewproblem2&cpid=993)
|
||||||
- Graphs
|
- Shortest Path
|
||||||
- Breadth First Search (BFS)
|
- Breadth First Search (BFS)
|
||||||
- ex. [Cow Navigation](http://www.usaco.org/index.php?page=viewproblem2&cpid=695)
|
- ex. [Cow Navigation](http://www.usaco.org/index.php?page=viewproblem2&cpid=695)
|
||||||
- Shortest Path (SP)
|
- Shortest Path (SP)
|
||||||
- ex. [Milk Pumping](http://www.usaco.org/index.php?page=viewproblem2&cpid=969)
|
- ex. [Milk Pumping](http://www.usaco.org/index.php?page=viewproblem2&cpid=969)
|
||||||
- Minimum Spanning Tree (MST)
|
- Minimum Spanning Tree (MST) & Disjoint Set Union (DSU)
|
||||||
- Disjoint Set Union (DSU)
|
- ex. [Fencedin](http://www.usaco.org/index.php?page=viewproblem2&cpid=623)
|
||||||
- ex. [Fencedin](http://www.usaco.org/index.php?page=viewproblem2&cpid=623)
|
- Topological Sort (TopoSort)
|
||||||
- Topological Sort (TopoSort)
|
- ex. [Timeline](http://www.usaco.org/index.php?page=viewproblem2&cpid=1017)
|
||||||
- ex. [Timeline](http://www.usaco.org/index.php?page=viewproblem2&cpid=1017)
|
|
||||||
- [Range Sum Queries with Point Updates](https://thecodingwizard.github.io/usaco-training-2.0/Gold_1DRQ)
|
- [Range Sum Queries with Point Updates](https://thecodingwizard.github.io/usaco-training-2.0/Gold_1DRQ)
|
||||||
- ex. [Haircut](http://www.usaco.org/index.php?page=viewproblem2&cpid=1041)
|
- ex. [Haircut](http://www.usaco.org/index.php?page=viewproblem2&cpid=1041)
|
||||||
- Number Theory
|
- Number Theory
|
||||||
- ex. [Cow Poetry](http://usaco.org/index.php?page=viewproblem2&cpid=897)
|
- ex. [Cow Poetry](http://usaco.org/index.php?page=viewproblem2&cpid=897)
|
||||||
- Less Common
|
- Hashing (NOT COMMON)
|
||||||
- Strings
|
- ex. [Cownomics](http://www.usaco.org/index.php?page=viewproblem2&cpid=741)
|
||||||
- Hashing
|
- Combinatorics (NOT COMMON)
|
||||||
- ex. [Cownomics](http://www.usaco.org/index.php?page=viewproblem2&cpid=741)
|
- Principle of Inclusion and Exclusion (PIE)
|
||||||
- Combinatorics
|
- ex. [Cowpatibility](http://usaco.org/index.php?page=viewproblem2&cpid=862)
|
||||||
- Principle of Inclusion and Exclusion (PIE)
|
- Sliding Window (NOT COMMON)
|
||||||
- ex. [Cowpatibility](http://usaco.org/index.php?page=viewproblem2&cpid=862)
|
- ex. [Haybale Feast](http://www.usaco.org/index.php?page=viewproblem2&cpid=767)
|
||||||
- Sliding Window
|
|
||||||
- ex. [Haybale Feast](http://www.usaco.org/index.php?page=viewproblem2&cpid=767)
|
|
||||||
|
|
||||||
# Platinum
|
# Platinum
|
||||||
|
|
||||||
|
|
Reference in a new issue