Você está na página 1de 4

#include <stdio.

h>
#include <stdlib.h>

struct dupla{
int vertices[100];
int tamanho;
};

// Funcao para somar as arestas, guardar os vertices de cada caminho menor, pegar o
ultimo vertice de i a j.
void soma_arestas(int vert, int count, int posicao, int result_1[vert][vert], int
result_2[vert][vert],
int matriz[vert][vert], int booleano[vert][vert], struct dupla dupla[vert][vert]){

for (int j = 1; j < vert; j++){


if (booleano[j][count] == 0 && matriz[posicao][j] &&
result_1[posicao][count] +
matriz[posicao][j] < result_1[j][count]){
// soma as arestas.
result_1[j][count] = result_1[posicao][count] +
matriz[posicao][j];
// guarda o valor do ultimo vertice de i a j, sem incluir
j.
result_2[j][count] = posicao;
}

// guardas os vertices do menor caminho.


if(booleano[j][count] == 0){
dupla[j][count].vertices[dupla[j][count].tamanho] = posicao;
++dupla[j][count].tamanho;
}
}
}

// Funçao para encontrar a menor aresta e retorna o indice i da aresta Kij;


int Distancia(int vert, int count, int result_1[vert][vert], int booleano[vert]
[vert]){
int menor = 10000, posicao;

for (int i = 1; i < vert; i++)


if (booleano[i][count] == 0 && result_1[i][count] <= menor){
menor = result_1[i][count];
posicao = i;
}
return posicao;
}

void Resposta(int vert, int ciclo, int count, int result_1[vert][vert], int
result_2[vert][vert],
struct dupla dupla[vert][vert], int caminhos, int requisitado[caminhos][vert+2]){

// Imprime apenas no ultimo ciclo.


if(ciclo == 0 && count == vert - 1){

//Imprime o peso dos caminhos.


for (int i = 1; i < vert; i++){
for(int j = 1; j < vert; j++){

if(j == 1)
printf("%d",(result_1[j][i] == 10000) ? -1 : result_1[j]
[i]);
else
printf(" %d",(result_1[j][i] == 10000) ? -1 : result_1[j]
[i]);
}
printf("\n");
}

// Imprime o ultimo vertice de i a j.


for (int i = 1; i < vert; i++){
for (int j = 1; j < vert; j++){

if(j == 1){
if(result_2[j][i] != 0)
printf("%d", result_2[j][i]);
else
printf("-");
}
else{
if(result_2[j][i] != 0)
printf(" %d", result_2[j][i]);
else
printf(" -");
}
}
printf("\n");
}
++ciclo;
}

// Imprime os casos requisitados que nao retiram nenhuma aresta.


if(ciclo == 1){

for(int i = 0; i < caminhos - 1; ++i){

if(requisitado[i][2] == 0){
printf("%d", result_1[requisitado[i][1]][requisitado[i][0]]);
printf(" %d", dupla[requisitado[i][1]][requisitado[i][0]].tamanho
+ 1);

for(int j = 0; j <= dupla[requisitado[i][1]][requisitado[i]


[0]].tamanho; ++j){

if(j < dupla[requisitado[i][1]][requisitado[i][0]].tamanho)


printf(" %d", dupla[requisitado[i][1]][requisitado[i]
[0]].vertices[j]);

if(j == dupla[requisitado[i][1]][requisitado[i][0]].tamanho)
printf(" %d", requisitado[i][1]);
}

if(i != caminhos - 1)
printf("\n");
}

if(requisitado[i][2] != 0){
printf("%d %d", -1, 0);
if(i != caminhos - 1)
printf("\n");
}
}
}

// Algoritimo de Djisktra.
void Algoritimo(int vert, int matriz[vert][vert], struct dupla dupla[vert][vert],
int caminhos,
int requisitado[caminhos][vert+2], int count, int ciclo){

// result_1 = peso do caminho do vertice i ate o j; result_2 = ultimo vertice


do caminho de i ate j,
// sem considerar j; booleano == guardar se o vertice i ja foi verificado.
int result_1[vert][vert], result_2[vert][vert], booleano[vert][vert];

// Na primeira chamada zerando as posicoes das matriz e result_1 para o


infinito.
if (count == 1){
for(int i = 1; i < vert; ++i){
for(int j = 1; j < vert; ++j){
result_1[i][j] = 10000;
result_2[i][j] = 0;
booleano[i][j] = 0;
}
}
}

result_1[count][count] = 0;

for(int i = 1; i < vert - 1; i++) {


// Pegar o valor da menor distancia de i a j.
int posicao = Distancia(vert, count, result_1, booleano);
// Marca esse vertice como verficado.
booleano[posicao][count] = 1;
// chama a funcao soma_arestas.
soma_arestas(vert, count, posicao, result_1, result_2, matriz,
booleano, dupla);
}

Resposta(vert, ciclo, count, result_1, result_2, dupla, caminhos,


requisitado);
}

// Inicializaçao.
int main(){

// Declaaraçao de variaveis.
int vert, arest, caminhos, temp[4];
scanf("%d%d%d", &vert, &arest, &caminhos);
vert += 1, caminhos += 1;
int matriz[vert][vert], requisitado[caminhos][vert+2];
struct dupla dupla[vert][vert];

// Zerando posicoes das matrizes.


for(int i = 1; i < vert; ++i)
for(int j = 1; j < vert; ++j)
matriz[i][j] = 0, dupla[i][j].tamanho = 0;

for(int i = 0; i < caminhos; ++i)


for(int j = 0; j < vert+2; ++j)
requisitado[i][j] = -1;

// Escaneando as arestas.
for(int i = 0; i < arest; ++i){
scanf("%d%d%d", &temp[1], &temp[2], &temp[3]);
matriz[temp[1]][temp[2]] = temp[3];
}

// Escaneando os casos requisitados.


for(int i = 0; i < caminhos - 1; ++i){
scanf("%d%d%d", &requisitado[i][0], &requisitado[i][1], &requisitado[i]
[2]);
for(int j = 0; j < requisitado[i][2]; ++j)
scanf("%d", &requisitado[i][j+3]);
}

// Chamando o Algoritimo.
for(int i = 1; i < vert; ++i)
Algoritimo(vert, matriz, dupla, caminhos, requisitado, i, 0);

/*3 4 3
1 2 8
1 3 5
2 1 3
3 2 2
1 2 1 2
2 3 1 3
1 3 0*/

return 0;
}

Você também pode gostar