Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
metodichka_SI.doc
Скачиваний:
30
Добавлен:
23.02.2015
Размер:
2.05 Mб
Скачать

2 Задача

Найти путь с наименьшей стоимостью из пункта A в пункт B. Вес ребра из пункта A в пункт B и из пункта В в пункт А один и тот же.

Дополнительное условие: данные о графе считываются из текстового файла и хранятся в виде треугольной матрицы. Граф задаётся как матрица смежности.

#include <stdio.h>

#include <stdlib.h>

// количество вершин

int n;

// матрица смежности графа

int**G;

// массив пометок

int*M;

// длина пути

int npath;

// начальная вершина пути

int A;

// конечная вершина пути

int B;

// массив для номеров вершин, включённых в путь из A в B

int*path;

// цена пути от вершины iдо вершиныj(0 <=> вершины не соединены ребром)

int g(int i,int j)

{

if (j < i)

return G[i][j];

else

if (j > i)

return G[j][i];

else

return0;

}

// выделение памяти под одномерный массив

void initarr(int*&A)

{

A = (int*)malloc(n*sizeof(int));

}

// выделение памяти под двумерный массив

void init2arr(int**&A)

{

A = (int**)malloc(n*sizeof(int*));

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

A[i] = (int*)malloc(i*sizeof(int));

}

// освобождение памяти после использования двумерного массива

void free2arr(int**&A)

{

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

free(A[i]);

free(A);

}

// освобождение памяти после использования всех нужных массивов

void FreeMem()

{

free2arr(G);

free(M);

free(path);

}

// загрузка данных из файла

void Input()

{

FILE*f;

// открытие текстового файла на считывание

f = fopen("graf4.txt","r");

// считывание количества вершин графа

fscanf(f,"%d",&n);

// инициализация всех нужных массивов

init2arr(G);

initarr(M);

initarr(path);

int i,j;

// считывание нижнго треугольника матрицы смежности графа, без главной диагонали

for (i=1; i<n; i++)

for (j=0; j<i; j++)

fscanf(f,"%d",&G[i][j]);

// считывание начального и конечного пунктов маршрута

fscanf(f,"%d%d",&A,&B);

// для нумерации вершин с 0, а не с 1

A--;B--;

// закрытие файла

fclose(f);

}

// поиск в ширину: ищется самый дешёвый маршрут из AвB

void FindPath(int A,int B)

{

int i,j;

// инициализация массива пометок

for(i=0;i<n;i++)

M[i] = -1;

M[A] = 0;

intb= 1;

// пока в массиве пометок происходят изменения

while (b)

{

b = 0;

for (i=0; i<n; i++)

if (M[i] >= 0)

for (j=0; j<n; j++) if (i != j)

if (g(i,j))

// (вj-ю вершину пока пути не проложено)

if ((M[j] == -1) || (M[i] + g(i,j) < M[j]))

{

// ИЛИ (попасть в j-ю вершину изi-ой дешевле, чем способом, найденным до этого)

M[j] = M[i] + g(i,j);

b= 1;

}

}

// если в вершину Bтак и не дошли

if (M[B] == -1)

npath= 0;

else

{

// иначе проходим от BкAи записываем найденный путь в массивpath

path[0] = B;

npath = 0;

j = B;

int d;

while (j != A)

{

i = 0;

d = 1;

while (d)

{

if (i != j)

if (g(i,j))

if (M[i] != -1)

d = (M[i] != M[j] - g(i,j));

i++;

}

j = i-1;

npath++;

path[npath] = j;

}

}

}

// вывод пути на экран

void PrintPath()

{

for (int i=npath; i>0; i--)

printf("%d ",path[i]+1);

printf("%d\n",path[0]+1);

}

intmain()

{

// загрузка данных из файла

Input();

// поиск в ширину: ищется самый дешёвый маршрут из AвB

FindPath(A,B);

printf("Path from A to B: ");

// вывод пути на экран

PrintPath();

// вывод стоимости

printf("It costs %d\n\n",M[B]);

// освобождение памяти после использования всех нужных массивов

FreeMem();

return0;

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]