Bienvenido(a), Visitante. Por favor, ingresa o regístrate.

Ingresar con nombre de usuario, contraseña y duración de la sesión

 
Búsqueda Avanzada

15.707 Mensajes en 3.130 Temas- por 371 Usuarios - Último usuario: lasfirrot
Mayo 22, 2012, 08:47:29
Foro de Hispabyte.netProgramaciónCompeticiones de programación y algorítmicaOlimpiada Informática Española / IOITema: Breadth First Search
Páginas: [1]   Ir Abajo
Imprimir
Autor Tema: Breadth First Search  (Leído 3179 veces)
0 Usuarios y 2 Visitantes están viendo este tema.
nachox
Novato
*
Mensajes: 18


Ver Perfil
« : 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
Administrator
Miembro Imprescindible
*****
Mensajes: 1.813



Ver Perfil
« 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
Administrator
Miembro Imprescindible
*****
Mensajes: 1.813



Ver Perfil
« Respuesta #2 : Enero 22, 2011, 09:08:31 »

Aqui tienes material interesante para la busqueda en anchura

http://www.competitiva.com.ar/archivos/Presentacion-8-Competitiva.pdf
En línea
Alex Alvarez
Novato
*
Mensajes: 6


Ver Perfil
« 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


Ver Perfil
« Respuesta #4 : Enero 24, 2011, 02:28:30 »

Gracias por el material HQH Cheesy. 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


Ver Perfil
« 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.
Código:
#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
Administrator
Miembro Imprescindible
*****
Mensajes: 1.813



Ver Perfil
« 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.html

Si tienes cualquier duda posteala
En línea
nachox
Novato
*
Mensajes: 18


Ver Perfil
« 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.

* oil-spill-1.pdf (28.4 KB - descargado 110 veces.)
En línea
Alex Alvarez
Novato
*
Mensajes: 6


Ver Perfil
« 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


Ver Perfil
« 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


Ver Perfil
« 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


Ver Perfil
« Respuesta #11 : Mayo 09, 2011, 07:01:48 »

Si se entiende la idea, pero no consigo realizar la implementación Triste. 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


Ver Perfil
« 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:
Código:
#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


Ver Perfil
« Respuesta #13 : Mayo 10, 2011, 06:10:46 »

Gracias Alex, ahora si me quedó claro el problema.
En línea
Páginas: [1]   Ir Arriba
Imprimir
Foro de Hispabyte.netProgramaciónCompeticiones de programación y algorítmicaOlimpiada Informática Española / IOITema: Breadth First Search
Ir a:  


Tema diseñado por RJ-45 para Hispabyte.net basado en el
theme famouspadexx v.09 designed by Formado Comprido
Downloable here. My present to padexx.de