Um grafo simétrico é conexo se existe um passeio de cada vértice aos demias vértices do grafo. Um grafo simétrico que não é conexo consiste de um conjunto de componentes conexas que são subgrafos conexos maximais.
Uma ponte ou aresta de corte de um garfo simétrico é uma aresta que se removida aumenta o número de componentes conexos.
PROBLEMA. Determinar as arestas de corte de um grafo simétrico dado.
Considere uma floresta de busca em profundidade do grafo dado. Para cada vértice u do grafo tem-se que u->min é o vértice v de menor númeração pré-ordem tal que
existe um arco de retorno de um descendente de u a v, com exceção feita ao arco de u ao seu predecessor na árvore de busca me profundidade.Após a execução da função abaixo vale que uv é uma aresta de corte se e somente se
#define estado z.I
#define pre_ordem y.I
#define min x.V
#define pred w.V
enum {NAOVISTO, VISITADO, EXAMINADO};
Boolean dfs_pontes (Vertex *r);
/*
* determina as arestas de corte do componente do grafo que
* contém o vértice r
*/
void
pontes (Graph *g)
{
Vertex *v0 = g->vertices;
Vertex *vn = g->vertices + g->n;
Vertex *v;
for (v = v0; v < vn; v++)
{
v->estado = NAOVISTO;
v->min = v;
}
for (v = v0; v < vn; v++)
{
if (v->estado == NAOVISTO)
{
v->pred = v;
dfs_pontes(v);
}
}
}
void
dfs_pontes (Vertex *r)
{
static long pre = 0;
Arc *a;
r->estado = VISITADO;
r->estado = ++pre;
for (a = r->arcs; a; a = a->next)
{
Vertex *v = a->tip;
if (v == r->pred) continue;
/* rv é um arco para frente (foward-arc) */
if (v->estado == EXAMINADO) continue;
/* rv é um arco de retorno */
if (v->estado == VISITADO && v->pre_ordem > r->min->pre_ordem) continue;
/* rv é um arco de retorno */
if (v->estado == VISITADO && v->pre_ordem < r->min->pre_ordem) r->min = v;
/* rv é um arco da árvore */
if (v->estado == NAOVISTO)
{
v->pred = r;
dfs_pontes(v);
if (v->min->pre_ordem < r->min->pre_ordem) r->min = v->min;
}
}
r->estado = EXAMINADO;
}