nachox
Novato

Mensajes: 18
|
 |
« : Enero 19, 2011, 01:42:06 » |
|
Hola a todos, acabo de leer algo de teorÃa sobre BFS, pero no se como aplicarlo, intenté resolver este problema http://acm.tju.edu.cn/toj/showp1056.html, sin éxito. Espero me puedan ayudar a resolverlo.
|
|
|
|
« Última modificación: Enero 19, 2011, 01:44:10 por nachox »
|
En línea
|
|
|
|
|
HQH
|
 |
« Respuesta #1 : Enero 21, 2011, 04:01:49 » |
|
Hola Amigo, ahora no tengo material para pasarte, te hare una mini contestacion y en un rato te pongo algo.
BFS --> Busqueda en anchura
Se puede usar para realizar una busqueda y necesite que se inspeccione todo en el mismo nivel de profundidad antes de pasar al siguiente.
En caminos, una busqueda en anchura nos puede ayudar a encontrar el camino mas corto SIEMPRE que el peso de dar un paso sea 1.
En tu problema, visto por encima es eso lo que tienes que hacer.
Espero te sirva de ayuda, un saludo.
|
|
|
|
|
En línea
|
|
|
|
|
HQH
|
 |
« Respuesta #2 : Enero 22, 2011, 09:08:31 » |
|
|
|
|
|
|
En línea
|
|
|
|
Alex Alvarez
Novato

Mensajes: 6
|
 |
« Respuesta #3 : Enero 23, 2011, 10:30:11 » |
|
Tan sólo un pequeño apunte. El problema que has escogido no es quizá el más apropiado para aprender a hacer un BFS. Si bien la solución requiere usarlo, no consiste en un simple BFS. El problema te está pidiendo que digas el máximo de las mÃnimas distancias entre pares de nodos. Como el grafo es siempre un árbol (te lo dice el enunciado) la solución emplea dos BFS: uno desde un nodo cualquiera y el siguiente desde el más alejado del primero. La máxima distancia en este segundo BFS es la que te piden.
|
|
|
|
|
En línea
|
|
|
|
nachox
Novato

Mensajes: 18
|
 |
« Respuesta #4 : Enero 24, 2011, 02:28:30 » |
|
Gracias por el material HQH  . Alex Alvarez, tu aporte me pareció interesante, tal vez conozcas unos problemas más indicados para aprender BFS, pues aún nunca lo he usado.
|
|
|
|
|
En línea
|
|
|
|
Alex Alvarez
Novato

Mensajes: 6
|
 |
« Respuesta #5 : Enero 24, 2011, 09:44:33 » |
|
Pues por ejemplo de la página de la OIE, el problema "Harrichu y el laberinto" del apartado "Búsquedas en grafos" lo puedes resolver con un simple BFS. Por si te interesa, te pongo mi solución aceptada en C++ del problema que dijiste inicialmente. #include <iostream> #include <vector> #include <queue> using namespace std;
const int INF = 1000000000; typedef pair<int, int> PII;
int n, m; int arrx[] = {0,0,1,-1}; int arry[] = {1,-1,0,0};
void bfs(int inix, int iniy, vector<vector<int> >& d, vector<vector<char> >& M) { d[inix][iniy] = 0; queue<PII> Q; Q.push(PII(inix, iniy)); while (not Q.empty()) { int x = Q.front().first, y = Q.front().second; Q.pop(); for (int i = 0; i < 4; ++i) { int nx = x + arrx[i], ny = y + arry[i]; if (nx < 0 or nx >= n or ny < 0 or ny >= m or M[nx][ny] == '#') continue; if (d[nx][ny] > d[x][y] + 1) { d[nx][ny] = d[x][y] + 1; Q.push(PII(nx, ny)); } } } }
int main() { int q; cin >> q; while (q--) { cin >> m >> n; vector<vector<char> > M(n, vector<char>(m)); int inix, iniy; for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { cin >> M[i][j]; if (M[i][j] == '.') { inix = i; iniy = j; } } } vector<vector<int> > d(n, vector<int>(m, INF)); bfs(inix, iniy, d, M); int maxdist = 0; for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { if (d[i][j] != INF and d[i][j] > maxdist) { maxdist = d[i][j]; inix = i; iniy = j; } } } d = vector<vector<int> >(n, vector<int>(m, INF)); bfs(inix, iniy, d, M); maxdist = 0; for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { if (d[i][j] != INF and d[i][j] > maxdist) maxdist = d[i][j]; } } cout << "Maximum rope length is " << maxdist << "." << endl; } }
|
|
|
|
|
En línea
|
|
|
|
|
HQH
|
 |
« Respuesta #6 : Enero 25, 2011, 06:41:53 » |
|
Me alegro el material te haya ayudado. Cualquier problema que sea encontrar el camino mas corto con coste 1 del paso, te vale un BFS Te paso un ejercicio que se resuelve con BFS http://uva.onlinejudge.org/external/100/10067.htmlSi tienes cualquier duda posteala
|
|
|
|
|
En línea
|
|
|
|
nachox
Novato

Mensajes: 18
|
 |
« Respuesta #7 : Mayo 07, 2011, 04:04:39 » |
|
Hola a todos, estaba muy ocupado, luego de un largo tiempo intente resolver el problema "Derrame de petróleo", que lo estoy adjuntando, pero no consigo resolverlo, agradecerÃa algunas ideas de como resolverlo. Ya se que se tiene que aplicar un bfs, pero eso de que pueden haber varios puntos de partida, me confunde un poco.
|
|
|
|
En línea
|
|
|
|
Alex Alvarez
Novato

Mensajes: 6
|
 |
« Respuesta #8 : Mayo 08, 2011, 08:56:22 » |
|
Cuando se tiene un BFS con múltiples orÃgenes, la idea es la misma. La única diferencia es que mientras que en un BFS con un solo origen se pone en la cola el origen y su distancia a cero, si hay varios se ponen todos ellos en la cola al principio, inicializando la distancia de todos ellos a cero.
|
|
|
|
|
En línea
|
|
|
|
nachox
Novato

Mensajes: 18
|
 |
« Respuesta #9 : Mayo 09, 2011, 12:12:55 » |
|
Gracias Alex Alvarez, y cómo puedo controlar lo de los instantes de tiempo, para que me imprima el mapa con las restricciones dadas.
|
|
|
|
|
En línea
|
|
|
|
Alex Alvarez
Novato

Mensajes: 6
|
 |
« Respuesta #10 : Mayo 09, 2011, 08:26:04 » |
|
Para eso puedes hacer un par de cosas distintas. Por la naturaleza de BFS, el grafo se recorre por niveles, es decir, primero los nodos a distancia 1, luego los que están a distancia 2, etc. En el problema, la distancia es equivalente al tiempo.
Una primera opción serÃa guardar un vector de distancia/tiempo para cada nodo y cada vez que sacas un nodo de la cola, comprobar si su distancia es diferente de la distancia del nodo sacado anteriormente. Si es asÃ, entonces es el primero de los nodos con esa distancia o tiempo, llamémosle tiempo t. Esto nos indica que todos los nodos con tiempo t - 1 ya han sido tratados, de forma que si t - 1 es uno de los tiempos, es momento de imprimir.
La otra opción es parecida, pero en vez de usar un vector de distancias o nodos, usa un par de colas y un entero que lleva el tiempo actual de los nodos que se visitan. Cuando sacas un nodo de la cola que estás usando, toda su adyacencia que toque explorar, la metes en la otra cola en lugar de esa. AsÃ, cuando la cola que estás usando se vacÃe es que has acabado los nodos de la distancia actual (que llevas contada en el entero), de forma que si ese tiempo es de los indicados en la entrada lo tienes que imprimir. Una vez hecho esto, incrementas el tiempo y haces un swap de las colas para seguir igual.
|
|
|
|
|
En línea
|
|
|
|
nachox
Novato

Mensajes: 18
|
 |
« Respuesta #11 : Mayo 09, 2011, 07:01:48 » |
|
Si se entiende la idea, pero no consigo realizar la implementación  . Si pudieras poner un pseudocódigo o el código del problema, me serÃa de mucha ayuda.
|
|
|
|
|
En línea
|
|
|
|
Alex Alvarez
Novato

Mensajes: 6
|
 |
« Respuesta #12 : Mayo 10, 2011, 12:42:05 » |
|
Con este código me da AC en el juez. He usado lo que he comentado de las dos colas: #include <iostream> #include <vector> #include <queue> using namespace std;
typedef pair<int, int> PII; typedef vector<int> VI; typedef vector<char> VC; typedef vector<VC> VVC;
int arrf[] = {1,-1,0,0}; int arrc[] = {0,0,1,-1};
void escribe(VVC& M, bool first) { if (not first) cout << string(M[0].size(), '=') << endl; for (int i = 0; i < M.size(); ++i) { for (int j = 0; j < M[i].size(); ++j) cout << M[i][j]; cout << endl; } }
int main() { int n, m; cin >> n >> m; VVC M(n, VC(m)); for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) cin >> M[i][j]; VI v; int t; while (cin >> t) v.push_back(t);
queue<PII> Q, Q2; for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { if (M[i][j] == 'X') { M[i][j] = '*'; Q.push(PII(i, j)); } } } int k = 0; t = 0; while (k < v.size()) { if (t == v[k]) escribe(M, k++ == 0); while (not Q.empty()) { int f = Q.front().first, c = Q.front().second; Q.pop(); for (int i = 0; i < 4; ++i) { int nf = f + arrf[i], nc = c + arrc[i]; if (nf < 0 or nf >= n or nc < 0 or nc >= m or M[nf][nc] != '.') continue; M[nf][nc] = '*'; Q2.push(PII(nf, nc)); } } ++t; swap(Q, Q2); if (Q.empty() and k < v.size()) t = v[k]; } }
|
|
|
|
|
En línea
|
|
|
|
nachox
Novato

Mensajes: 18
|
 |
« Respuesta #13 : Mayo 10, 2011, 06:10:46 » |
|
Gracias Alex, ahora si me quedó claro el problema.
|
|
|
|
|
En línea
|
|
|
|
|