Aula 11 - Aplicações de Busca em Grafos
Universidade Federal do Rio Grande do Sul
Instituto de Informática
Departamento de Informática Teórica
Estes slides utilizam conteúdo adaptado da bibliografia da disciplina e também de notas de aula e slides prévios dos professores Bruno Grisci, Rodrigo Machado, André Grahl Pereira, Lucas Nunes Alegre, Marcus Ritt e Luciana Buriol.
Diversos problemas elementares em grafos simples e dígrafos podem ser eficientemente resolvidos utilizando buscas (DFS ou BFS).
Exemplos:
Árvore de Busca. Dada uma busca (DFS ou BFS) em G a partir de um nó v, construir uma árvore associada a essa busca onde cada nó aponta para o elemento que o alcançou diretamente.
parent, preenchido ao inserirmos um nó na estrutura.Cálculo de Distância. Dado um grafo simples ou dígrafo G e um nodo v, determinar um vetor de distâncias de v para todos os nodos de G.
BFS já fornece a distância:
Implementação:
Observações:
- DFS não pode ser utilizada para cálculo de distância. Por quê?
- Assumimos que G não possui pesos nas arestas.
Conectividade. Dado um grafo simples ou dígrafo G e dois nodos a e b, determinar se a está conectado a b.
Solução: Iniciar busca (DFS ou BFS) em a, comparando o nodo atual com b. Se achar, retorna True. Se a busca terminar sem achar b, retorna False.
Rota entre Nodos. Dado um grafo simples ou dígrafo G e dois nodos a e b, determinar uma rota iniciando em a e terminando em b.
Solução: Iniciar busca (DFS ou BFS) em a produzindo a árvore de busca. Ao achar b, a rota entre a e b é a inversão do caminho de b até a na árvore de busca.
Rota com Menor Número de Arestas. Dado um grafo simples ou dígrafo G e dois nodos a e b, determinar uma rota com o menor número de arestas entre a e b.
Solução: Como no caso de rota, porém utilizando exclusivamente BFS.

Componentes Conexos (UCC). Dado um grafo simples G, determinar o número de componentes conexos e quais os nós contidos em cada um (Undirected Connected Components).
Teste de Bipartição. Dado um grafo simples G, determinar se G é bipartido (isto é, se seus vértices podem ser particionados em dois conjuntos independentes V_1 e V_2, ou equivalentemente, se não possui ciclos ímpares).
Conforme visto, um grafo é bipartido se e somente se não possuir ciclos ímpares. Esta caracterização nos fornece um algoritmo bastante eficiente baseado em coloração de nodos e BFS para testar bipartição.
cor que associa true (cor 1) ou false (cor 0) a cada nodo.Ordenamento Topológico. Dado um dígrafo acíclico (DAG) G = (V, E), encontrar uma sequência linear v_1, v_2, \ldots, v_n contendo todos os vértices de V tal que, para toda aresta direcionada (v_i, v_j) \in E, o vértice origem v_i precede o vértice destino v_j na sequência (isto é, i < j).
Exemplo:
Alguns possíveis ordenamentos topológicos para G_5:
Algoritmo de Kahn (1962) para ordenamento topológico:
inDeg) e iniciar uma lista q contendo nodos de grau zero a serem processadosBusca em profundidade (DFS) também pode ser utilizada para determinar ordenamento topológico.
pos após o retorno de todas as chamadas recursivas de DFS geradas por ele.pos.insert(0, v), garantimos que as dependências apareçam antes de seus sucessores na lista final.Componentes Fortemente Conexos (SCC). Dado um dígrafo G = (V, E), decompor V em componentes fortemente conexos (Strongly Connected Components), onde cada componente é um subdígrafo conexo maximal no qual todo par de vértices é mutuamente alcançável.
Diferentemente de grafos simples, por conta da direcionalidade dos arcos, pode haver mais de um componente mesmo que o dígrafo pareça estar “em um único pedaço”.
Componentes fortemente conexos (nodos):
Componentes: [1, 3, 5], [11], [6, 8, 10], [2, 4, 7, 9]
Kosaraju (e Shamir, independentemente) descobriram que, ao rodar ordenamento topológico sobre um dígrafo arbitrário (não necessariamente acíclico), temos que o primeiro nodo do ordenamento obrigatoriamente pertence a um componente fonte (source).
Solução:
toposortsobre o grafo reverso (G^R)! Isso gera uma sequência de nodos que pode ser usada para guiar uma busca por componentes no grafo original que nunca inclui mais do que o componente atual de cada nodo.
Detecção de Ciclos. Dado um grafo simples, pseudografo ou dígrafo G, determinar a existência de ciclos (se G contém pelo menos um ciclo).
Há diferenças importantes entre os modelos com arcos unidirecionais ou bidirecionais:
Ideia principal: Para cada componente conexo (nó ainda não visitado), iniciamos uma busca em profundidade (DFS) e mantemos o nó pai de cada vértice.
Ideia principal: Rodar o algoritmo de ordenamento topológico de Kahn sobre o dígrafo (baseado em graus de entrada).
Podemos usar DFS e BFS para resolver diversos problemas em grafos simples e dígrafos de forma eficiente.
Complexidade Linear: \Theta(|V| + |E|)
?