Update Silver_Graphs.md

This commit is contained in:
Benjamin Qi 2020-06-03 19:48:39 -04:00
commit 899e268871

View file

@ -71,6 +71,8 @@ The most common example of a two-colored graph is a *bipartite graph*, in which
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
//UNTESTED
bool is_bipartite = true;
void dfs(int node)
{
@ -101,6 +103,8 @@ void dfs(int 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.
A related topic is **strongly connected components**, a platinum level concept.
### Functional Graphs
Links:
@ -112,13 +116,13 @@ In silver-level directed cycle problems, it is generally the case that each node
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.
(test code?)
```cpp
//UNTESTED
//Each node points to next_node[node]
bool visited[MAXN], on_stack[MAXN];
int number_of_cycles = 0;
int number_of_cycles = 0, next_node[MAXN];
void dfs(int n)
{
visited[n] = on_stack[n] = true;
@ -138,7 +142,51 @@ int main()
}
```
For non-functional directed graphs, this code will still detect a cycle if it exists (though `number_of_cycles` will be meaningless).
The same general idea is implemented below to find any cycle in a directed graph.
```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
@ -149,5 +197,3 @@ For non-functional directed graphs, this code will still detect a cycle if it ex
- [CSES Round Trip (undirected)](https://cses.fi/problemset/task/1669)
- [CSES Round Trip II (directed)](https://cses.fi/problemset/task/1678)
Cycle finding is also related to **strongly connected components**, a platinum level concept.