Laboratório No. 07

Descrição:

O conjunto de páginas web na internet pode ser considerado um grafo, onde uma página é um vértice e uma ligação (link) é uma aresta direcionada.

Estima-se que o número de páginas indexadas pelo Google seja da ordem de 2*10^9 (2 bilhões). Além disso, se estimarmos grosseiramente que cada página contém uma média de 100 links para outras páginas, teremos algo da ordem de 2*10^11 links nas páginas indexadas pelo Google.

Usando uma representação em grafos, teríamos um grafo com 2 bilhões de vértices e 200 bilhões de arestas. Se o grafo fosse completo, teríamos cerca de (2*10^9)^2 = 4*10^18 ou 4 quintilhões de arestas. Portanto podemos considerar esse tipo de grafo como um grafo esparso, o que justificaria adotar uma estrutura de lista de adjacências ao invés de uma matriz de adjacência para representá-lo.

Objetivo:

Suponha que o Google esteja contratando programadores no Brasil para extrair algumas estatísticas à respeito dos sites indexados. Seu objetivo vai ser implementar as funções para obter esses dados a partir de um grafo direcionado representando um conjunto de páginas web na internet.

Certamente, se fôssemos utilizar todos os sites indexados no Google como entrada para esse laboratório, a quantidade de memória total consumida seria muito maior do que a soma da memória de todas as máquinas dos laboratórios do IC-3. Portanto, iremos considerar apenas um subconjunto pequeno de páginas.

Como já constatamos, a melhor estrutura para representar esse grafo seria uma lista de adjacências. E é sobre essa estrutura que suas funções devem operar. Veja um exemplo:

  +-----------------------------+
  |                             |   +---+    +---+
0 | www.ic.unicamp.br           |-> | 1 | -> | 2 |
  |                             |   +---+    +---+
  +-----------------------------+
  |                             |   +---+    +---+
1 | www.ic.unicamp.br/staff     |-> | 0 | -> | 4 |
  |                             |   +---+    +---+
  +-----------------------------+
  |                             |   +---+    +---+
2 | www.ic.unicamp.br/grad      |-> | 0 | -> | 3 |
  |                             |   +---+    +---+
  +-----------------------------+
  |                             |   +---+
3 | www.ic.unicamp.br/~ra000000 |-> | 0 |
  |                             |   +---+
  +-----------------------------+
  |                             |   +---+    +---+    +---+
4 | www.ic.unicamp.br/~fulano   |-> | 0 | -> | 2 | -> | 3 |
  |                             |   +---+    +---+    +---+
  +-----------------------------+

Neste pequeno exemplo, a página 0 (www.ic.unicamp.br) possui link para a página 1 e 2, já a página 3 (www.ic.unicamp.br/~ra000000) possui link apenas para a página 0.

Para facilitar a aplicação das funções, será fornecido um simples interpretador para os seguintes comandos:

imprimealcancaveis url
Imprime as páginas alcançadas a partir da página com nome url.
ciclo
Imprime se existe ou não ciclo no grafo.
paginamaispopular
Imprime a página que recebe mais links (isto é, a página que tem mais links que levam à ela)
caminhominimo url1 url2
Imprime o menor caminho entre a página de origem url1 e a página de destino url2.
imprime
Imprime o grafo
libera
Libera a memória alocada pelo grafo.
sair
Termina a execução do programa.

Exemplo de entrada:

O arquivo de entrada conterá uma descrição da lista de adjacências, dessa forma:

5
www.ic.unicamp.br 2 1 2
www.ic.unicamp.br/staff 2 0 4
www.ic.unicamp.br/grad 2 0 3
www.ic.unicamp.br/~ra000000 1 0
www.ic.unicamp.br/~fulano 3 0 2 3

Onde a primeira linha contém o número n de vértices do grafo. Seguida por n linhas, sendo que a primeira palavra é o endereço da página web, seguida pelo número de páginas adjacentes d, seguida por d números inteiros. Os índices dos vértices das páginas devem ser atribuídos na mesma ordem seqüencial dada na entrada, começando em 0.

O arquivo de entrada completo será:

  1. A primeira linha conterá o nome da função a ser testada.
  2. Seguida pela descrição da lista de adjacências, como mostrado acima.
  3. As linhas subseqüentes serão compostas dos comandos do interpretador.

Por exemplo:

InserePagina
5
www.ic.unicamp.br 2 1 2
www.ic.unicamp.br/staff 2 0 4
www.ic.unicamp.br/grad 2 0 3
www.ic.unicamp.br/~ra000000 1 0
www.ic.unicamp.br/~fulano 3 0 2 3
imprime
paginamaispopular
caminhominimo www.ic.unicamp.br www.ic.unicamp.br/~fulano
caminhominimo www.ic.unicamp.br/~fulano www.ic.unicamp.br/~fulano
caminhominimo www.ic.unicamp.br/~fulano www.ic.unicamp.br/~ra000000
caminhominimo www.ic.unicamp.br/grad www.ic.unicamp.br/~fulano
existeciclo
imprimealcancaveis www.ic.unicamp.br
libera
sair

Implementação e saída:

Durante a leitura da descrição da lista de adjacências, você deverá alocar e preencher a estrutura de memória para representação da mesma, usando as funções apropriadas. Os nós de cada lista deverão ser mantidos ordenados pela ordem do índice do vértice.

Para o exemplo acima, uma saída seria:

Testando apenas a função `InserePagina´.
=== Pagina : Links ===
www.ic.unicamp.br : www.ic.unicamp.br/staff www.ic.unicamp.br/grad
www.ic.unicamp.br/staff : www.ic.unicamp.br www.ic.unicamp.br/~fulano
www.ic.unicamp.br/grad : www.ic.unicamp.br www.ic.unicamp.br/~ra000000
www.ic.unicamp.br/~ra000000 : www.ic.unicamp.br
www.ic.unicamp.br/~fulano : www.ic.unicamp.br www.ic.unicamp.br/grad www.ic.unicamp.br/~ra000000
=== Total: 5 paginas web ===
Página mais popular: www.ic.unicamp.br com 4 link(s)
Menor caminho entre www.ic.unicamp.br e www.ic.unicamp.br/~fulano: 2 link(s)
Menor caminho entre www.ic.unicamp.br/~fulano e www.ic.unicamp.br/~fulano: 0 link(s)
Menor caminho entre www.ic.unicamp.br/~fulano e www.ic.unicamp.br/~ra000000: 1 link(s)
Menor caminho entre www.ic.unicamp.br/grad e www.ic.unicamp.br/~fulano: 3 link(s)
O grafo possui ciclo(s).
www.ic.unicamp.br: www.ic.unicamp.br/staff www.ic.unicamp.br/grad www.ic.unicamp.br/~ra000000 www.ic.unicamp.br/~fulano

Testes:

Haverá 7 grupos de teste, um para cada função a ser testada. Os arquivos de cada grupo são iguais, variando apenas a função testada em cada um deles. E serão, repectivamente, InserePagina, InsereLink, DestroiGrafo, BuscaPaginaMaisPopular, BuscaCaminhoMinimo, ExisteCiclo, ImprimePaginasAlcancaveis.

Observações adicionais:

  1. Você deve submeter apenas o arquivo pagina.c.
  2. Você não deve modificar, ou remover as partes do código entre #ifndef ... #endif no início de cada função.
  3. A sua última submissão deve incluir todos os casos, testando todas as funções.
  4. As listas de adjacências devem estar ordenadas em ordem crescente do índice do vértice, e as operações sobre adjacentes devem obedecer essa ordem.