tpl220171012.cpp

#define USECHRONO
#include "eval.hpp"
#include <cassert>
#include <climits>
#include <cstdlib>
#include <stack>
#include <map>

using namespace aed;
using namespace std;

/* COMIENZO DE DESCRIPCION

   __USE_WIKI__

   #prom-nivel:# Dado un arbol #T,# calcular una lista de
   reales #P,# donde el elemento #l# de la lista sea el
   promedio de los nodos del arbol de nivel #l.#

   #es-circuito:# Dado un grafo #G# representado por un map
   de nodos a lista de vecinos, y una lista de nodos #L,#
   escriba una funcion que determine si la secuencia de
   nodos #L# es un camino dentro del grafo #G.#

   #map-graph:# Dado un grafo #Gin# y una permutacion #P,#
   encontrar el grafo #Gout# que resulta de permutar los
   vertices de #Gin# por la pertmutacion #P,# es decir si la
   arista #(j,k)# esta en #Gin,# entonces la arista
   #(P[j],P[k])# debe estar en #Gout.#

   [Tomado en el TPL2 de 2017-10-12].  
   keywords: correspondencia, arbol orientado

FIN DE DESCRIPCION */

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
// Funcion recursiva, acumula en N y S por nivel la cantidad
// de nodos y suma de sus elementos
void prom_nivel(tree<int> &T, tree<int>::iterator it, 
                int level, map<int,int> &N, map<int,int> &S) {
  if (it==T.end()) return;
  S[level]+=*it; N[level]++; level++;
  for(auto it2=it.lchild();it2!=T.end();++it2)
    prom_nivel(T,it2,level,N,S);
}

void prom_nivel(tree<int> &T, list<float> &P) {
  if (T.begin()==T.end()) return;
  // Llama a la funcion auxiliar y calcula las sumas y
  // numero de nodos
  map<int,int> N;
  map<int,int> S;
  prom_nivel(T,T.begin(),0,N,S);
  // Va calculando el promedio
  for(auto p:N) {
    P.push_back(float(S[p.first])/p.second);
  }
}

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
// Retorna `true' si x esta en `L'
bool contiene(list<int>&L,int x){
  for(auto y : L)
    if(y == x) return true;
  return false;
}

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
bool es_circuito(map<int,list<int>>&G,list<int>&L){
  // Recorre los elementos de L
  list<int>::iterator it = L.begin();
  while(it!=L.end()){
    // En cada iteracion it y ++it son dos vertices
    // consecutivos en L
    map<int,list<int>>::iterator itg = G.find(*it);
    ++it;
    // Es el siguiente (o begin()) si
    // llegamos al final
    auto z = (it==L.end()?*L.begin():*it);
    if(!contiene(itg->second,z)) return false;
  }
  return true;
}

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
void unique(vector<int> &v) {
  // Using a map (could be a set)
  map<int,int> M;
  for (auto &x : v) M[x] = 1; // 1 or whatever
  v.clear();
  for (const auto &q : M) v.push_back(q.first);
  sort(v.begin(),v.end()); // No hace falta...
}

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
void map_graph(map<int,vector<int> > &Gin,map<int,int> &P,
               map<int,vector<int> > &Gout) {
  Gout.clear();
  for (auto const &q : Gin) {
    int j = q.first;
    const vector<int> &ngbrs = q.second;
    for (auto const &k : ngbrs) {
      // (j,k) es la arista en Gin
      int Pj=P[j], Pk=P[k];
      Gout[Pj].push_back(Pk);
    }
  }
  // Ordena los ngbrs de Gout y elimina repetidos
  for (auto & q : Gout) unique(q.second); 
}

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
int main() {
  Eval ev;
  int vrbs = 0;
  int seed = 123;
  int h1=0,h2=0,h3=0;

  // User typical call
  ev.eval<1>(prom_nivel,vrbs);
  h1 = ev.evalr<1>(prom_nivel,seed,vrbs);

  ev.eval<2>(es_circuito,vrbs);
  h2 = ev.evalr<2>(es_circuito,seed,vrbs);

  ev.eval<3>(map_graph,vrbs);
  h3 = ev.evalr<3>(map_graph,seed,vrbs);

  printf("S=%03d -> H1=%03d H2=%03d H3=%03d\n",
         seed,h1,h2,h3);
  
  return 0;
}

Generated by GNU Enscript 1.6.6.