tpl220161013.cpp
#define USECHRONO
#include "eval.hpp"
#include <cassert>
#include <climits>
#include <cstdlib>
#include <stack>
using namespace aed;
using namespace std;
/* COMIENZO DE DESCRIPCION
__USE_WIKI__
#unordered-equal:#
Escribir una funcion bool que
reciba dos Arboles Ordenados Orientados (AOO) y retorne #true# si
son desordenadmente iguales. Es decir si se pueden transformar uno en el otro
conpermutaciones en la lista de hermanos de cada nod.
#hay-camino:# Un viajante quiere viajar desde una
ciudad a otra siguiendo algun camino del grafo conexo de rutas
#M.# Lamentablemente se tiene la informacion de que en algunas
ciudades hay piquetes y es imposible pasar por ellas. Para
determinar si es posible realizar el viaje se debe implementar una
funcion, que recibe el mapa de rutas disponibles (cada arista del grafo
representa una ruta directa disponible entre las ciudades de los
vortices que conecta), y la lista de ciudades con piquetes. La
funcion debe retornar verdadero si existe alguna ruta que comience
en la ciudad #cini# y finalice en #cend# sin pasar por ninguna de las
ciudades con piquetes.
#enhance-html:# Los desarrolladores de un sitio web
desean resaltar los links que aparecen dentro de cada
pagina del sitio. Para ello es necesario que cada link
(tag #<a># en HTML) se encuentre dentro de un tag
#<strong>.# Para resolver este problema ya contamos con
un parser del codigo HTML que lo representa en un
#tree<string>.# Escribir una funcion que recorre dicho
arbol y si encuentra una hoja con tag #a# le agrega un padre #strong#.
[Tomado en el Trabajo Practico de Laboratorio Nro 2
(TPL2) de 2016-10-13].
keywords: correspondencia, arbol orientado
FIN DE DESCRIPCION */
bool unordered_equal(tree<int> &A,tree<int> &B,
tree<int>::iterator itA,
tree<int>::iterator itB) {
map<int,tree<int>::iterator> MA, MB;
for(auto it = itA.lchild(); it!=A.end(); ++it) MA[*it] = it;
for(auto it = itB.lchild(); it!=B.end(); ++it) MB[*it] = it;
if (MA.size()!=MB.size())
return false;
for (auto itMA = MA.begin(), itMB = MB.begin(); itMA!=MA.end(); ++itMA, ++itMB) {
if (itMA->first!=itMB->first)
return false;
if (!unordered_equal(A,B,itMA->second,itMB->second))
return false;
}
return true;
}
bool unordered_equal(tree<int> &A,tree<int> &B) {
if (*A.begin()!=*B.begin())
return false;
return unordered_equal(A,B,A.begin(),B.begin());
}
//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
// Otra posibilidad: Hace que cada arbol este en forma
// `canonica' es decir que todos sus hijos estan ordenados.
// make_canonical(T) -> hace que T quede en forma canonica
// Entonces podemos hacer make_canonical(A),
// make_canonical(B) y despues retornar A==B, ya que son
// `unordered_equal' si y solo si sus formas canonicas son iguales.
typedef tree<int>::iterator node_t;
void make_canonical(tree<int> &T, node_t n) {
if (n==T.end()) return;
// M contiene para los hijos de `n': *c -> subarbbol de c
// Lo hace con splice
map<int,tree<int> > M;
node_t c = n.lchild(),d;
while (c!=T.end()) {
d = c; d++;
tree<int> &C = M[*c];
c = C.splice(C.begin(),c);
c = n.lchild();
}
// Ahora recorre los hijos de n y les vuelve a aplicar el
// make_canonical recursivamente a los hijos y los vuelve
// a insertar como hijos de `n'
c = n.lchild();
for (auto q=M.begin(); q!=M.end(); q++) {
tree<int> &C = q->second;
make_canonical(C,C.begin());
auto cb = C.begin();
c = T.splice(c,cb);
}
}
bool unordered_equal2(tree<int> &A,tree<int> &B) {
make_canonical(A,A.begin());
make_canonical(B,B.begin());
return A==B;
}
//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
bool hay_camino(map<string,list<string> > &M, string cini, string cfin,
map<string,bool> visited) {
visited[cini] = true;
auto &L = M[cini];
for(auto &cvec:L) {
if (cvec==cfin)
return true;
if (!visited[cvec] && hay_camino(M,cvec,cfin,visited))
return true;
}
return false;
}
bool hay_camino(map<string,list<string> > &M, list<string> &P,
string cini, string cfin) {
map<string,bool> visited;
for(auto &p:M)
visited[p.first] = false;
for(string &c:P)
visited[c] = true;
return hay_camino(M,cini,cfin,visited);
}
//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
void enhance_html(tree<string> &T, string father,
tree<string>::iterator it) {
if (*it=="a" && father!="strong") {
*it="strong";
T.insert(it.lchild(),"a");
} else {
for(auto c = it.lchild(); c!=T.end(); ++c) {
enhance_html(T,*it,c);
}
}
}
void enhance_html(tree<string> &T) {
enhance_html(T,"",T.begin());
}
//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
int main() {
Eval ev;
int vrbs = 0;
int seed = 123;
int h1=0,h2=0,h3=0;
ev.eval<1>(unordered_equal2,vrbs);
h1 = ev.evalr<1>(unordered_equal,seed,vrbs);
ev.eval<2>(hay_camino,vrbs);
h2 = ev.evalr<2>(hay_camino,seed,vrbs);
ev.eval<3>(enhance_html,vrbs);
h3 = ev.evalr<3>(enhance_html,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.