dagdesc.cpp

/* COMIENZO DE DESCRIPCION

   __USE_WIKI__
   Dados un Grafo Dirigido Aciclico (DAG) #G=(V,E)# y un
   subconjunto de vertices #W\subseteq V#, determinar el conjunto
   $D\subseteq V$ de *descendientes* de #W#, es decir #d\in D# si
   y solo si existe un camino que va de algun nodo #w\in W# a #d#. 

   [Tomado en el 3er parcial de 2012-11-22].  
   keywords: conjunto, correspondencia

  FIN DE DESCRIPCION */
// -------------------------------------------------------------------

#include <cstdio>
#include <cassert>
#include <cmath>

#include <map>
#include <set>

#include "./util.h"

using namespace std;

typedef map<int, set<int> > graph_t;

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
void dag_desc(graph_t &G,set<int> &W, set<int> &D) {
  // El frente que avanza es guardado en el conjunto `front'
  set<int> front = W;
  // Inicializa el conjunto de descendientes como el
  // la fuente W
  D = W;
  while (!front.empty()) {
    // Toma un vertice `v' del frente
    int v = *front.begin();
    front.erase(v);
    // Lo pone en el conjunto de descendientes
    D.insert(v);
    // Recorre los vecinos `r' de `v'
    set<int> &ngbrs = G[v];
    set<int>::iterator r = ngbrs.begin();
    while (r!=ngbrs.end()) {
      // Si `r' no fue visitado agregarlo al frente
      if (D.find(*r)==D.end())
        front.insert(*r);
      r++;
    }
  }
}

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
// Imprime el grafo
void print_graph(const graph_t &G) {
  graph_t::const_iterator q = G.begin();
  while (q!=G.end()) {
    printf("%d -> {",q->first);
    const set<int> &ngbrs = q->second;
    set<int>::const_iterator r = ngbrs.begin();
    while (r!=ngbrs.end()) 
      printf("%d ",*r++);
    printf("}\n");
    q++;
  }
}

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
// Lee un grafo de un int[]. Se insertan las aristas como
// pares de enteros y termina con un -1. Asume que no hay
// nodos desconexos (sin ninguna arista) y que los vertices
// son >=0
void read_graph_directed(graph_t &G, const int *g) {
  const int *p = g;
  while (*p>=0) {
    int 
      v1 = *p++,
      v2 = *p++;
    G[v1].insert(v2);
  }
}

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
int main() {
  graph_t G4,G5;

  // Crea el grafo del ejemplo en el parcial
  int g4[] = {0,1, 0,2, 2,1, 2,3, 1,3, 1,5, 
              1,4, 5,6, 6,7, 3,4, 4,7, 3,7, -1};
  read_graph_directed(G4,g4);
  printf("G4: -------- \n");
  print_graph(G4);

  set<int> W,D;
  W.insert(5);
  W.insert(3);

  dag_desc(G4,W,D);
  printf("D: {");
  set<int>::iterator q = D.begin();
  while (q!=D.end()) {
    printf("%d ",*q);
    q++;
  }
  printf("}\n");
  
  return 0;
}

Generated by GNU Enscript 1.6.6.