Ejemplo n.º 1
0
        int visitaDfs(int u, vector <int> & cor)
        {
            int t=0;
            cor[u] = CINZA;

            //printf("%d ", u);

            int a=0, v=grafo.ProxAdj(u, a++);
            while(v>=0){
                if(cor[v] == BRANCO){
                    t = visitaDfs(v, cor);
                    if(t>d[u])
                        d[u]=t;
                }
                else{
                    if(d[v]+1>d[u])
                        d[u]=d[v]+1;
                }

                v = grafo.ProxAdj(u, a++);
            }

            cor[u] = PRETO;

            return d[u]+1;
        }
Ejemplo n.º 2
0
void componentes_fuertes(const Grafo<C> & g, Lista<Lista<int> > & componentes)
{
     // se asume que los vertices fueron numerados de 0 a long-1
     bool visitado[g.devolverLongitud()];
     for (int i = 0; i < g.devolverLongitud(); i++)
	  visitado[i] =  false;
     
     Lista<int> vertices;
     Lista<int> recorrido;
     g.devolverVertices(vertices);
     Lista<int>::Iterador it_v = vertices.devolverIterador();
     while (!it_v.llegoAlFinal()) {
	  int v = it_v.elementoActual();
	  if (!visitado[v])
	       dfs_visit(g, v, visitado, recorrido);
	  it_v.avanzar();
     }

     Grafo<C> g_trasp;
     traspuesta_grafo(g, g_trasp);

     for (int i = 0; i < g.devolverLongitud(); i++)
	  visitado[i] =  false;
     
     it_v = recorrido.devolverIterador();
     while (!it_v.llegoAlFinal()) {
	  int v = it_v.elementoActual();
	  if (!visitado[v]) {
	       Lista<int> componente;
	       dfs_visit(g_trasp, v, visitado, componente);
	       componentes.agregarFinal(componente);
	  }
	  it_v.avanzar();
     }
}
Ejemplo n.º 3
0
void build_test_graph(Grafo & g)
{
  g.insert_node("A");
  g.insert_node("B");
  g.insert_node("C");
  g.insert_node("D");
  g.insert_node("E");
  g.insert_node("F");
  g.insert_node("G");
  g.insert_node("H");
  g.insert_node("I");

  insertar_arco(g, "A", "B", 2);
  insertar_arco(g, "A", "F", 5);
  insertar_arco(g, "B", "F", 1);
  insertar_arco(g, "B", "D", 3);
  insertar_arco(g, "C", "A", 1);  
  insertar_arco(g, "C", "E", 4);  
  insertar_arco(g, "F", "D", -2);
  insertar_arco(g, "F", "C", -1);
  insertar_arco(g, "F", "E", 2);
  insertar_arco(g, "D", "F", 2);
  insertar_arco(g, "D", "H", 4);
  insertar_arco(g, "E", "G", 2);
  insertar_arco(g, "E", "I", -2);
  insertar_arco(g, "G", "D", 3);
  insertar_arco(g, "G", "F", -1);
  insertar_arco(g, "G", "H", 2);
  insertar_arco(g, "H", "D", -2);
  insertar_arco(g, "H", "G", -1);
  insertar_arco(g, "I", "G", 4);
  insertar_arco(g, "I", "H", 3);

}
std::vector<int> Grafo::OrdemTopologica() {
	std::vector<int> listaOrdenado;
	std::vector<int> lSemArestas;
	Grafo * clone = new Grafo(*this);
	int id;
	bool dag = true;
	lSemArestas = clone->GetConjVertices();
	while ((int) lSemArestas.size() > 0) {
		id = lSemArestas[0];
		lSemArestas.erase(lSemArestas.begin());
		clone->RemoveVertice(id);
		//cout << "lSemArestas[0]: " << lSemArestas[0] << endl;
		//remova um nodo n de S
		//insira n em L
		listaOrdenado.push_back(id);

		if ((int) lSemArestas.size() == 0) {
			lSemArestas.clear();
			lSemArestas = clone->GetConjVertices();
			if ((int) lSemArestas.size() == 0 && clone->nrElementos > 0) {
				dag = false;
				break;
			}
			//for (int i =0; i < (int) lSemArestas.size(); i++)
			//	cout << "lSemArestas[i]: " << lSemArestas[i] << endl;
		}
	}
	if (!dag) {
		listaOrdenado.clear();
	}
	return listaOrdenado;
}
Ejemplo n.º 5
0
        void visitaBfs(int u, vector <int> & cor)
        {
            cor[u] = CINZA;
            d[u] = 0;
            queue <int> fila;

            fila.push(u);

            while(!fila.empty()){
                u = fila.front();
                fila.pop();

                int a=0, v=grafo.ProxAdj(u, a++);
                while(v>=0)
                {
                    if(cor[v] == BRANCO){
                        cor[v] = CINZA;
                        d[v] = d[u]+1;
                        antecessor[v] = u;
                        fila.push(v);
                    }
                    v = grafo.ProxAdj(u, a++);
                }
                cor[u] = PRETO;
            }
        }
Ejemplo n.º 6
0
int main(int argc, char *argv[])
{
     const int n = 3;
     enum {A, B, C};
     Grafo<int> g;
     g.agregarVertice(A);
     g.agregarVertice(B);
     g.agregarVertice(C);

     g.agregarArco(A, B, 1);
     g.agregarArco(B, C, 1);
     g.agregarArco(C, A, 1);

     bool visitado[n];
     bool hay_ciclo =  false;
     int i = 0;
     while (!hay_ciclo && i < n) {
	  for (int k = 0; k < n; k++)
	       visitado[k] = false;

	  hay_ciclo = ciclo_hamilton(g, i, visitado, 0, i);
	  i++;
     }
     if (hay_ciclo)
	  cout << "hay ciclo de hamilton" << endl;
     else
	  cout << "no hay ciclo de hamilton" << endl;
     return 0;
}
Ejemplo n.º 7
0
int main(int argc, char **argv)
{
	Grafo<int> g;
	enum {A, B, C, D};
	const int n = 4;
	g.agregarVertice(A);
	g.agregarVertice(B);
	g.agregarVertice(C);
	g.agregarVertice(D);

	g.agregarArco(A, B, 1);
	g.agregarArco(A, C, 1);
	g.agregarArco(C, B, 1);
	g.agregarArco(B, D, 1);

	Lista<int> camino_parcial;
	Lista<Lista<int> > caminos;
	int tiempo = 0;
	
	bool visitado[n];
	for (int i = 0; i < n; i++)
	{
		visitado[i] = false;
	}
	caminos_simples(g, A, D,
			visitado, caminos, camino_parcial);
	const char impr[] = "ABCD";
	mostrar_caminos(g, caminos, impr);
	
	return 0;
}
Ejemplo n.º 8
0
        bool operator =(Grafo<int> &g) {

            if (this == &g)
                return *this;

            vaciar();

            list<int> v;
            g.getVertices(v);
            list<int>::iterator it = v.begin();

            while ( it != v.end()) {
                list<int> ady;
                g.getAdyacentes(*it, ady);
                agregarVertice(*it);
                list<int>::iterator itad = ady.begin();

                while ( itad != ady.end()) {
                    agregarArcoNoDireccional(*it, *itad);
                    itad++;
                }

                it++;
            }
        }
void DlgConsultarArista::aceptar(wxCommandEvent &event)
{

    wxString inicio = inicios->GetValue();
    wxString destino = destinos->GetValue();

    wxChar ini = inicio.GetChar(0);
    wxChar dest = destino.GetChar(0);

    char i = (char) ini;
    char d = (char) dest;

    if (drawpanel != NULL){
		Grafo* g = drawpanel->getGrafo();
		int pesoArista = g->consultarArista(i, d);
		if (pesoArista != -1){
            peso->Clear();
            peso->AppendText( wxString::Format(wxT("%i"),pesoArista)  );
		}
		else{
            peso->Clear();
            peso->AppendText( wxT("N/E") );
		}
    }
}
Ejemplo n.º 10
0
ComponentesConexas::ComponentesConexas(Grafo const& G) : marked(G.V(), false), _id(G.V()),
    _size(G.V(),0), _count(0) {
        for (auto v = 0; v < G.V(); ++v) {
            if (!marked[v]) { // se recorre una nueva componente conexa
                dfs(G, v);
                ++_count;
            }
        }
    }
Ejemplo n.º 11
0
int main(int argc, char *argv[])
{
     enum {a, b, c, d, e, f, g, h};
     const int n = 8;

     Grafo<int> gr;
     for (int i = 0; i < n; i++)
	  gr.agregarVertice(i);
     
     gr.agregarArco(a, b, 1);
     gr.agregarArco(b, f, 1);
     gr.agregarArco(b, c, 1);
     gr.agregarArco(b, e, 1);
     gr.agregarArco(c, d, 1);
     gr.agregarArco(c, g, 1);
     gr.agregarArco(d, c, 1);
     gr.agregarArco(d, h, 1);
     gr.agregarArco(e, a, 1);
     gr.agregarArco(e, f, 1);
     gr.agregarArco(f, g, 1);
     gr.agregarArco(g, f, 1);
     gr.agregarArco(h, h, 1);
     
     Lista<Lista<int> > componentes;
     componentes_fuertes(gr, componentes);
     mostrar_componentes(componentes, "abcdefgh");
     return 0;
}
Grafo::Grafo(const Grafo & cGrafo) {
	this->direcionado = cGrafo.Direcionado();
	this->tamGrafo = cGrafo.GetTamGrafo();
	this->nrElementos = cGrafo.GetElementos();
	this->debug = false;
	this->lVertice = new Vertice [ this->tamGrafo ];
	for (int i = 0; i < this->tamGrafo; i++) {
		Vertice * nVertice = new Vertice(cGrafo.GetVertice(i));
		this->lVertice[i] = *nVertice;
	}
}
Ejemplo n.º 13
0
void buscarCaminoMinimo(int cantidadEstaciones, int cantidadVias, int* vias){	
	Grafo fortaleza = Grafo(vias, cantidadEstaciones, cantidadVias); //fancy arreglo de listas enlazadas

	int distance[cantidadEstaciones];
	int prev[cantidadEstaciones];
	int salida = cantidadEstaciones - 1;	
	//la cola de prioridad, true si ya lo visitamos
	bool noVisitados[cantidadEstaciones];
	
	for(int i = 0; i < cantidadEstaciones; i++){
		distance[i] = -1;
		prev[i] = -1;
		noVisitados[i] = true;
	}

	distance[0] = 0;
	int actual;
	std::list<Arista>* vecinos; 
	std::list<Arista>::iterator posActual;

	while( (actual = masCercano(noVisitados, distance, cantidadEstaciones)) != -1 ){ //O(n)
	
		noVisitados[actual] = false; //lo saco de la "cola"
		if(actual == salida) break; //ya tiene una distancia y prev asignados
		
		vecinos = fortaleza.vecinos(actual);
		for(posActual = vecinos->begin(); posActual != vecinos->end(); ++posActual){ 
			Arista v = *posActual;
			int alt = distance[actual] + v.peso; //si la distancia la guarda el nodo: v.distance;
			if( alt < distance[v.destino] || distance[v.destino] == -1){
				distance[v.destino] = alt;
				prev[v.destino] = actual;
			}

		}
	}

	//recorrer el arreglo prev y ahi tengo los vertices necesarios.
	int j = salida;
	//printf("%d\n", distance[j]);
	if(distance[j] != -1){
		std::list<int> output;
		std::list<int>::iterator itOut;
		while( j >= 0 ){
			output.push_front(j);
			j = prev[j]; //prev[0] esta en -1 entonces ahi corta el ciclo
		}
		//printf( "%lu\n", output.size() );
		for(itOut = output.begin(); itOut != output.end(); ++itOut){ 
		//	printf("%d ", *itOut + 1); //imprimo estaciones
		}
		//printf("\n");
	}
}
Ejemplo n.º 14
0
Grafo * Reader::getSteiner(int * &terminais, int * vet_size){
    string linha;
    int entrada, saida, forca;
    int size;
    
    inputFile.open(input_name);
    
    while (inputFile >> linha){
        if (linha == "Nodes")
            break;
    }
    
    inputFile >> linha;
    
    size = atoi(linha.c_str());
    
    Grafo * g = new Grafo(size);
    
    inputFile >> linha;
    inputFile >> linha;
    
    while(inputFile >> linha){
        if(linha == "END")
            break;
        inputFile >> entrada;
        inputFile >> saida;
        inputFile >> forca;
        g->adicionaRelacao((entrada % size), (saida % size), forca);
    }
    
    inputFile >> linha;
    inputFile >> linha;
    inputFile >> linha;
    
    inputFile >> *vet_size;
    
    terminais = new int [*vet_size];
    
    int i = 0;
    
    while(inputFile >> linha){
        if(linha == "END")
            break;
        
        inputFile >> terminais[i];
        i++;
    }
    
    inputFile.close();
    
    return g;

}
Ejemplo n.º 15
0
int main()  
{
  {
    Grafo g; // grafo con un punto de corte

    construir_grafo(g); 

    ofstream f("test-cut.Tree", ios::trunc);

    write_df_low_tree(g, g.get_first_node(), f);

  }
}
Ejemplo n.º 16
0
Grafo<unsigned int> Prim2opt::getMinimumSpanningTree(int raiz[], unsigned int costo[], unsigned int N, unsigned int r) {
    Grafo<unsigned int> g;

    for (unsigned int i = 1; i < N; i++) {
        g.addVertex(i);
    }
    for (unsigned int i = 1; i < N; i++) {
        if (i != r)
            g.addNonDirectionalEdge(i, raiz[i], costo[i]);
    }

    return g;
}
Ejemplo n.º 17
0
void imprimir_arcos(Grafo & g, const long & color)
{
  cout << "Listado de arcos con color " << color << endl;
  for (Grafo::Arc_Iterator it(g); it.has_current(); it.next())
    {
      Grafo::Arc * arc = it.get_current_arc();

      if (g.get_counter(arc) == color)
	cout << "Arco de " << g.get_src_node(arc)->get_info().clave
	     << " a " << g.get_tgt_node(arc)->get_info().clave << endl;
    }
  cout << endl;
}
Ejemplo n.º 18
0
int main()
{
    Grafo *g;
    GrafoMatriz gm;
    //GrafoLista gl;
    carregaGrafo *c;

    cout << "********************* GRAFO MATRIZ *****************************" << endl;

    g = &gm;

    c = new carregaGrafo(g);
    c->carregaDeArquivo();

    buscaEmGrafo b1(g);
    cout << "Grafo em matriz de adjacencia: " << endl;
    cout << "- impressao do grafo:" << endl;
    g->imprimeGrafo();
    cout << "- caminho mais curto por Dijkstra: " << endl;
    g->caminhoMaisCurtoD(0);
    cout << "- caminho mais curto por Ford Bellman: " << endl;
    g->caminhoMaisCurtoFB(0);
    cout << "- fluxo maximo por Ford & Fullkerson: "<<endl;
    g->fluxoMaximo(0,5);

    cout << "- busca em profundidade: " << endl;
    //b1.buscaProfundidade();
    cout << "- busca em largura: " << endl;
    //b1.buscaLargura();

    /*cout << "********************* GRAFO LISTA *****************************" << endl;

    delete c;

    g = &gl;
    c = new carregaGrafo(g);
    c->carregaDeArquivo();

    buscaEmGrafo b2(g);
    cout << endl;
    cout << "Grafo em lista de incidencia: " << endl;
    cout << "- impressao do grafo:" << endl;
    g->imprimeGrafo();
    cout << "- busca em profundidade: " << endl;
    b2.buscaProfundidade();
    cout << "- busca em largura: " << endl;
    b2.buscaLargura();
    */
    delete c;
    return 0;
}
Ejemplo n.º 19
0
void imprimir_arcos_corte(Grafo & g)
{
  cout << "Listado de arcos de corte *** " << endl;
  for (Grafo::Arc_Iterator it(g); it.has_current(); it.next())
    {
      Grafo::Arc * arc = it.get_current_arc();

      if (g.get_control_bits(arc).get_bit(Aleph::Cut))
	cout << "Arco de " << g.get_src_node(arc)->get_info().clave
	     << " a " << g.get_tgt_node(arc)->get_info().clave 
	     << " con color " << g.get_counter(arc) << endl;

    }
  cout << endl;
}
Ejemplo n.º 20
0
void Prim2opt::TravelingSalesman(Grafo<Ciudad> &g, unsigned int r) {
    unsigned int visited[g.getSize()];
    for (unsigned int i = 0; i <= g.getSize(); i++)
    	visited[i] = 0;

    Grafo<unsigned int> T = getPrim(g, 0);
    list<unsigned int> L;
    preorderTreeWalk(T, r, visited, L);
    //L.push_back(r); Eso por si se quiere hacer realmente hamiltoniano.
    localSearch(g, L);
    printList(L);
    cout <<" - ";
    cout << getTourCost(g, L) << endl;

}
Ejemplo n.º 21
0
void crear_arco(Grafo & g, int isrc, int itgt)
{
  Grafo::Node * src = g.search_node(isrc);
  if (src == NULL)
    src = g.insert_node(isrc);

  Grafo::Node * tgt = g.search_node(itgt);
  if (tgt == NULL)
    tgt = g.insert_node(itgt);

  if (search_arc<Grafo>(g, src, tgt) != NULL)
    throw std::invalid_argument("Duplicated arc");

  g.insert_arc(src, tgt);
}
Ejemplo n.º 22
0
 BuscaEmLargura(Grafo g)
 {
     grafo = g;
     int n = grafo.getNumVertices();
     d.resize(n, INT_MAX);
     antecessor.resize(n, -1);
 }
Ejemplo n.º 23
0
void busqueda_local_primer_criterio(Grafo& G, vector<int>& solucionInicial) {
    // Criterio de Vecindad 1: Cambiamos k vertices por 1 vertice, donde k > 1
  int n = G.size();
  // Genero soluciones vecinas
  for (int u = 0; u < n; u++) {
    vector<int> solucionAuxiliar = solucionInicial;
    if (solucionInicial[u] == NO_INCLUIDO && G[u].size() > 1) {
      int cantINCLUIDOS = 0;
      solucionAuxiliar[u] = INCLUIDO;
      // Me fijo si el vectice NO INCLUIDO tiene al menos dos vectores adyacentes INCLUIDOS
      for (list<int>::iterator itAdyU=G[u].begin(); itAdyU != G[u].end(); ++itAdyU) {
        int v = *itAdyU;
        if (solucionInicial[v] == INCLUIDO) {
          cantINCLUIDOS ++;
          solucionAuxiliar[v] = NO_INCLUIDO;
        }
      }
      // Necesito al menos 2 INCLUIDOS
      if (cantINCLUIDOS > 1) {
        int cantCambiosPosibles = 0;
        bool esSolucion = solucion_posible(G, solucionAuxiliar, cantCambiosPosibles);
        if (esSolucion) {
          // Encontre una solucion Vecina mejor, fin del ciclo
          busqueda_local_primer_criterio(G, solucionAuxiliar);
          solucionInicial = solucionAuxiliar;
          break;
        }
      }

    }
  }
}
Ejemplo n.º 24
0
void busqueda_local_segundo_criterio(Grafo& G, vector<int>& solucionInicial) {
  // Criterio de Vecindad 2: Cambiamos k vertices por, a lo sumo, k-1 vertices, , donde k > 1
  int n = G.size();
  // Genero soluciones vecinas
  for (int u = 0; u < n; u++) {
    vector<int> solucionAuxiliar = solucionInicial;
    if (solucionInicial[u] == NO_INCLUIDO && G[u].size() > 1) {
      // Para los INCLUIDOS en la solucionInicial me fijo en sus adyacentes para encontrar algun adyacente que tambien esta INCLUIDO
      int cantINCLUIDOS = 0;
      solucionAuxiliar[u] = INCLUIDO;
      for (list<int>::iterator itAdyU=G[u].begin(); itAdyU != G[u].end(); itAdyU++) {
        int v = *itAdyU;
        if (solucionInicial[v] == INCLUIDO) {
          cantINCLUIDOS ++;
          solucionAuxiliar[v] = NO_INCLUIDO;
        }

      }
      // Necesito al menos 2 INCLUIDOS
      if (cantINCLUIDOS > 1) {
        int cantCambiosPosibles = cantINCLUIDOS - 2;
        bool esSolucion = solucion_posible(G, solucionAuxiliar, cantCambiosPosibles);
        if(esSolucion){
          // Encontre una solucion Vecina mejor, fin del ciclo
          busqueda_local_segundo_criterio(G, solucionAuxiliar);
          solucionInicial = solucionAuxiliar;
          break;
        }
      }
    }
  }
}
Ejemplo n.º 25
0
Grafo::Grafo(const Grafo& orig)
{
    if (orig.cntVrt > 0)
    {
        this->cntVrt = orig.cntVrt;
        arrVrt.resize(this->cntVrt);
        for (int i = 0; i < this->cntVrt; i++)
        {
            arrVrt[i].e = orig.obtEst(i);
            arrVrt[i].tmpChqVrs = orig.obtTmpChqVrs(i);
            arrVrt[i].cntChqVrs = orig.arrVrt[i].cntChqVrs;
            for (int j = 0; j < orig.arrVrt[i].lstAdy.size(); j++)
                arrVrt[i].lstAdy.push_back(orig.arrVrt[i].lstAdy[j]);
        }
    }
}
Ejemplo n.º 26
0
        void buscaEmLargura(int u)
        {
            int n = grafo.getNumVertices();
            vector <int> cor(n, BRANCO);

            visitaBfs(u, cor);
        }
Ejemplo n.º 27
0
void CargarEntrada(Grafo& grafo, Vertice& u, Vertice& v, double& K) 
{
	unsigned int cantVertices;
	unsigned int cantAristas;
	unsigned int numVerticeInicial;
	unsigned int numVerticeFinal;

	cin >> cantVertices >> cantAristas >> numVerticeInicial >> numVerticeFinal >> K;
	assert(cantVertices > 0 && "cantidad de vertices incorrecta");
	assert(cantAristas >= 0 && "cantidad de aristas incorrecta");
	assert(numVerticeInicial > 0 && numVerticeFinal > 0 && numVerticeFinal <= cantVertices && numVerticeInicial <= cantVertices && "vertices u,v incorrectos");
	assert(K > 0 && "K incorrecto");
	
	grafo = Grafo(cantVertices);
	u = Vertice(numVerticeInicial);
	v = Vertice(numVerticeFinal);
	
	for (unsigned int i = 1; i <= cantAristas; i++) {

		unsigned int v1;
		unsigned int v2;
		double peso1;
		double peso2;
		
		cin >> v1 >> v2 >> peso1 >> peso2;
		assert(0 < v1 && v1 <= cantVertices && 0 < v2 && v2 <= cantVertices && "aristas incorrectas");
		assert(peso1 >= 0 && peso2 >= 0 && "pesos incorrectos");
		
		Arista e = Arista(Vertice(v1), Vertice(v2), peso1, peso2);
		grafo.AgregarArista(e);

	}

	cin.ignore(1); //Ignora el newline a continuación, dejando como siguiente caracter el primer dato de la próxima instancia.
}	
Ejemplo n.º 28
0
void insertar_arco(Grafo &        grafo, 
		   const string & src_name, 
		   const string & tgt_name)
{
  Grafo::Node * n1 = grafo.search_node(Nodo(src_name));

  if (n1 == NULL)
    n1 = grafo.insert_node(src_name);

  Grafo::Node * n2 = grafo.search_node(Nodo(tgt_name));

  if (n2 == NULL)
    n2 = grafo.insert_node(tgt_name);

  grafo.insert_arc(n1, n2);
}
Ejemplo n.º 29
0
void build_test_graph_1(Grafo & g)
{
  g.insert_node(Nodo("E"));

  insertar_arco(g, "A", "B");
  insertar_arco(g, "A", "D");
  insertar_arco(g, "B", "C");
  insertar_arco(g, "C", "A");
  insertar_arco(g, "D", "E");
  insertar_arco(g, "E", "B");
  insertar_arco(g, "E", "D");

  insertar_arco(g, "E", "G");

  insertar_arco(g, "G", "F");
  insertar_arco(g, "F", "G");

  insertar_arco(g, "E", "H");

  insertar_arco(g, "H", "I");

  insertar_arco(g, "I", "J");
  insertar_arco(g, "J", "K");
  insertar_arco(g, "K", "I");
}
Grafo * build_graph()
{
  Grafo * g = new Grafo;

  for (int i = 'A'; i <= 'P'; ++i)
    g->insert_node(new Grafo::Node(i));

  insertar_arco(g, "A", "B", 3);
  //  insertar_arco(g, "B", "A", 3);
  insertar_arco(g, "B", "C", 4);
  insertar_arco(g, "C", "D", 3);
  insertar_arco(g, "D", "E", 4);
  insertar_arco(g, "E", "K", 2);
  insertar_arco(g, "K", "P", 7);
  insertar_arco(g, "P", "J", 1);
  insertar_arco(g, "J", "K", 4);
  insertar_arco(g, "K", "D", 5);
  insertar_arco(g, "D", "J", 2);
  insertar_arco(g, "J", "I", 2);
  //  insertar_arco(g, "I", "J", 2);
  insertar_arco(g, "I", "D", 1);
  insertar_arco(g, "I", "C", 2);
  insertar_arco(g, "I", "H", 2);
  insertar_arco(g, "H", "C", 3);
  insertar_arco(g, "H", "B", 7);
  insertar_arco(g, "B", "G", 1);
  insertar_arco(g, "B", "M", 15);
  //  insertar_arco(g, "M", "B", 3);
  insertar_arco(g, "M", "G", 10);
  insertar_arco(g, "G", "A", 4);
  insertar_arco(g, "A", "F", 9);
  insertar_arco(g, "F", "G", 5);
  insertar_arco(g, "F", "L", 10);
  insertar_arco(g, "F", "M", 12);
  insertar_arco(g, "H", "M", 8);
  insertar_arco(g, "L", "M", 4);
  insertar_arco(g, "M", "N", 2);
  insertar_arco(g, "N", "H", 3);
  insertar_arco(g, "N", "I", 1);
  insertar_arco(g, "N", "O", 3);
  insertar_arco(g, "O", "I", 3);
  insertar_arco(g, "O", "J", 1);
  insertar_arco(g, "O", "P", 6);

  return g;    
}