Você está na página 1de 4

UNIVERSIDADE PRESBITERIANA MACKENZIE

- Faculdade de Computação e Informática –


Ciência da Computação
Teoria dos Grafos – 06G
‘ Prova 2 – 23 de novembro de 2021
Professor: Fabio Lubacheski

Esta prova pode ser feita em dupla ou individualmente, basta que somente um dos integrantes
entregue um arquivo pdf com as repostas das questões abaixo, o arquivo deve conter o seguinte
cabeçalho no início do arquivo.

Nós,

Nome completo e TIA (1º integrante)


Nome completo e TIA (2º integrante)

declaramos que

todas as respostas são fruto de nosso próprio trabalho,


não copiamos respostas de colegas externos a dupla,
não disponibilizamos nossas respostas para colegas externos a dupla e
não realizamos quaisquer outras atividades desonestas para nos beneficiar ou prejudicar outros.

Imagine que agora que cada vértice de um grafo não-dirigido é um ponto no plano cartesiano, veja um exemplo de um
grafo com 6 vértices e seus respectivos pontos no plano cartesiano:

vértices 0 1 2 3 4 5
pontos (1,3) (2,1) (6,5) (3,4) (3,7) (5,3)

e o custo de uma aresta v-w é igual ao comprimento do segmento de reta que liga os pontos v e w no plano.

1) (1,5 ponto) Considere a estrutura TGrafo que utiliza uma matriz de adjacência para armazenar os vértices de um
grafo não-dirigido.
typedef struct{
int V; // quantidade de vertices
int A; // quantidade de arestas
float **adj; // matriz de adjacência
}TGrafo;

Rescreva a estrutura TGrafo para armazenar os pontos no plano cartesiano associado aos vértices do grafo, explique
textualmente como é associado o vértice ao ponto no plano cartesiano. Aqui você pode criar outra estrutura e
incluir na estrutura TGrafo, mas necessariamente a modificação deve estar contida na estrutura.

Lembre-se que as arestas, e consequentemente, as distâncias entre os pontos, continuam sendo armazenadas na
matriz float **adj;
2) (1,5 pontos) Considere abaixo a implementação da função Init() descrita abaixo:
TGrafo * Init(int V){
int i;
TGrafo *grafo=(TGrafo*)calloc(1,sizeof(TGrafo));
grafo->A=0;
grafo->V=V;
grafo->adj=(float**)calloc(grafo->V,sizeof(float *));
for( i=0;i<grafo->V;i++)
grafo->adj[i] = (float*)calloc(grafo->V,sizeof(float));

return grafo;
}

Rescreva a função para que, além de alocar a estrutura e a matriz, faça a alocação da estrutura que irá armazenar os
pontos referentes aos vértices do grafo. Aqui não é necessário preencher a estrutura que armazena os pontos, com
os pontos associados aos vértices, isso será feito na próxima questão.

3) (1,5 ponto) Escreva uma função que recebe um grafo (TGrafo), o número de vértice e as coordenadas x,y do ponto no
plano cartesiano por parâmetro, a sua função associa o ponto no plano cartesiano ao vértice correspondente, a
declaração da função seria:
void InserePontoVértice(TGrafo *G, int vertice, int x, int y){

4) (1,5 pontos) Considere abaixo a implementação da função insereA() que insere uma aresta na estrutura TGrafo:
void insereA(TGrafo *G, int v, int w){
if(G->adj[v][w]==0){
G->adj[v][w]= G->adj[w][v]=1; // grafo não-dirigido sem peso nas arestas
G->A++;
}
}

Rescreva a função para que, além de inserir a aresta v-w, faço o cálculo peso da aresta, ou seja, a distância entre os
pontos dos vértices v e w. Considere que os pontos (x,y) referentes aos vértices v e w já estão preenchidos na
estrutura proposta no exercício 1.
5) (4,0 pontos) Considere o algoritmo Kruskal visto em sala:
Algoritmo Kruskal( G )
Entrada: um grafo G com V vértices e A arestas
Saída: uma árvore T com V vértices e V-1 arestas = AGM
Estrutura auxiliar: Conjunto A com as arestas e os seus respectivos pesos e o conjunto de componentes.
início
Construir e ordenar A (conjunto de arestas) pelos custos das arestas
N ← |V|
T ← {}
Inicializar o conjunto de componentes (cada vértice de G é um componente)
enquanto T contém menos de N – 1 arestas e A não vazio faça
(u, v) ← aresta de menor peso em A
A ← A – (u, v)
comp_u ← Find(u) // retorna a componente onde está o vértice u
comp_v ← Find(v) // retorna a componente onde está o vértice v
se comp_u ≠ comp_v então
Merge(comp_u, comp_v)
T ← T U {(u, v)}
fim-se
fim-enquanto
retorne T
Fim.

Apresente a implementação para o algoritmo de Kruskal considerando que a entrada do algoritmo é um grafo não-
dirigido G (uma variável da estrutura TGrafo) e um vértice v do grafo. Na implementação do Kruskal você precisa
mostrar claramente como são definidos os conjuntos componentes e as implementações das sub-rotinas Find() e do
Merge() , observe que algoritmo retorna uma estrutura do tipo TGrafo com a AGM obtida, assim a função que
implementa o algoritmo poderia ter a seguinte declaração.
TGrafo * Kruskal(TGrafo *G){.....}

Considere a função main() para as implementações acima

int main(){
TGrafo *G = Init(6);
// insere para cada vértice o seu ponto no plano cartesiano
InserePontoVertice(G,0,1,3);
InserePontoVertice(G,1,2,1);
InserePontoVertice(G,2,6,5);
InserePontoVertice(G,3,3,4);
InserePontoVertice(G,4,3,7);
InserePontoVertice(G,5,5,3);

insereA(G,0,1);
insereA(G,0,3);
insereA(G,0,4);
insereA(G,1,5);
// aqui você deve inserir mais arestas para o Kruskal funcionar.
...
printf(“grafo de entrada”);
show(G);
TGrafo *T = Kruskal(G);
show(T);
....
}

Boa Prova !

Você também pode gostar