This repository has been archived on 2022-06-22. You can view files and clone it, but cannot push or open issues or pull requests.
usaco-guide/content/2_Silver/Silver_Graphs.md
2020-06-03 15:55:05 -07:00

4.7 KiB

Silver - Graphs

Author: Siyong Huang

Overview

  • Prerequisites
  • Depth First Search (DFS)
  • Flood Fill
  • Graph Two-Coloring
  • Cycle Detection

Prerequisites

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.

Tutorial

Problems

Flood Fill

Flood Fill refers to finding the number of connected components in a graph, frequently on a grid.

Tutorial

Problems

Graph Two-Coloring

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

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.

bool is_bipartite = true;
void dfs(int node)
{
	visited[node] = true;
	for(int u:adj_list[node])
		if(visited[u])
		{
			if(color[u] == color[node])
				is_bipartite = false;
		}
		else
		{
			color[u] = !color[node];
			dfs(u);
		}
}

Problems

Cycle Detection

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 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

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.

//Each node points to next_node[node]

bool visited[MAXN], on_stack[MAXN];
int number_of_cycles = 0;
void dfs(int n)
{
	visited[n] = on_stack[n] = true;
	int u = next_node[n];
	if(on_stack[u])
		number_of_cycles++;
	else if(!visited[u])
		dfs(u);
	on_stack[n] = false;
}
int main()
{
	//read input, etc
	for(int i = 1;i <= N;i++)
		if(!visited[i])
			dfs(i);
}

Problems