Все возможные пути между двумя вершинами в графе не пеpесекающиеся по pебpам .

Найти кратчайшее расстояние между двумя вершинами в графе. Найти все возможные пути между этими двумя вершинами в графе не пеpесекающиеся по pебpам
Задача 4(а) на графы (см. "Сборник задач по графам").

Алгоритм :
1) С помощью алгоритма Форда-Беллмана находим кратчайшее расстояние между двумя вершинами в графе и сам путь .
2) Устанавливаем вес всех рёбер равным единице
3) Снова применяем алгоритм Форда-Беллмана , при этом удаляем ребра по которым проходит путь (находим пути между этими двумя вершинами в графе не пеpесекающиеся по pебpам ).
4) Выполняем пункт 3) пока существуют новые пути .

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#define P 60
#define MAX 1000               //машинный эквивалент бесконечности
 
int m[P][P];                       // матрица для вычисления кратчайшего пути и его длины
int v[P][P];                       // матрица для нахождения всех возможных путей между данными вершинами в графе , не пеpесекающихся по pёбpам 
int D[P], G[P][P], W[P][P],Z[P];
int N,M,S,F;
int a,b,c;
int i,j,k,l,h,f;
 
void GRAF (int m[P][P]) {         // функция нахождения кратчайшего пути
 
   for (i=1 ; i<=N ; i++ )
    D[i] = m[S][i];               // массив , содержащий расстояния от заданной вершины до всех остальных 
    D[S] = 0 ;
 
   for (j=1; j<=2 ; j++) {        // матрица , хранящая путь из заданной вершины до всех остальных  
    G[j][1]=S;
    G[S][j]=0;
   }
 
 
   for (h=1 ; h<=N ;h++) {                // Алгоритм Форда-Беллмана
    i=0;
    for (j=2 ; j<=N ; j++) {
     for (k=1 ; k<=N ; k++) {
 
      if (D[k] > D[j]+m[j][k])
	D[k]=D[j]+m[j][k] ;
	i++;
 
	for (l=2 ; l<=N ; l++) {
	 W[i][l]=D[l];                    // преобразуем для удобства массив расстояний в матрицу  (i-ая строка матрицы - массив расстояний на i-ом шаге )
	 if (W[i][l]<W[i-1][l])           // отслеживаем улучшение пути
	  G[k][2]=j ;                     // запоминаем вершину через которую проходит этот путь
	}
     }
    }
   }
 
    printf("\n");
 
  if (D[F]<MAX) {                                         // если путь существует , то ...
 
    printf("\nдлина пути от %d узла до %d узла = ",S,F);
    printf("%d \n",D[F]);                                 // выводим длину пути 
 
    printf("путь между %d u %d вершинами  : ",S,F);
 
    i=1;
    Z[0]=F;
 
    while ( G[F][2] !=0 ) {                               // в массив Z записываем вершины , через которые проходит путь , в обратном порядке (от конечной к начальной вершине)
     Z[i]=G[F][2];
     i++;
     G[F][2]=G[G[F][2]][2];
    }
     Z[i]=S;
 
   for (j=i ; j>=0 ;j--)
    printf(" %d",Z[j]);                                   // выводим вершины , через которые проходит путь , в правильном порядке
 
  }
     else {                                               // если пути нет , то ...
      printf("\nпути нет\n\n\n");                 
      return;
     }
 
return;
 
}
 
void PYTU () {                     // функция нахождения всех возможных путей между данными вершинами в графе не пеpесекающиеся по pебpам 
 
   while (D[F]<MAX)  {             // пока путь существует ... 
    GRAF(v);                       // вызываем функцию нахождения кратчайшего расстояния для нашего графа без учета весов рёбер (все ребра имеют вес = 1)
    for (j=0 ; j<M ; j++)
    v[Z[j+1]][Z[j]]=MAX;           // пройденные ребра удаляем (ставим вес = бесконечности )  
   }
 
  return;
}
 
 
int main () {
 
clrscr();
 
 
 char fileName[256];
   FILE *inp;
 
   printf("Введите адрес : ");          // Например : D:\lab.txt 
    scanf("%s", fileName);
    printf("\n");
 
    inp=fopen(fileName, "r");          // открываем файл на чтение
 
    fscanf (inp,"%d %d",&N,&M);        // Читаем из файла первую строку , содержащую число вершин N и число ребер M
 
   for ( i=1 ; i<=N ; i++)             // присваиваем элементам обоих матриц максимальные значения 
    for ( j=1 ; j<=N ; j++) {
     m[i][j]=MAX;
     v[i][j]=MAX;
    }
 
   for (i=1 ;i<=M ;i++ ) {                // Читаем из файла остальные M строк , 
    fscanf(inp,"%d %d %d",&a,&b,&c);     // содержащие описание ребер (Пример строки файла :" 1 3 6 ": значит, что ребро из вершины 1 в вершину 3 имеет вес 6)  
       m[a][b]=c;                        // Заполняем матрицу смежностей для нашего графа , учитывая вес рёбер
   //  m[b][a]=1;                        // если граф неориентированный , то убрать метку 
       v[a][b]=1;                        // заполняес матрицу смежностей без учёта веса рёбер (все ребра имеют вес = 1)
   }
    fclose(inp);                         // закрываем файл
 
     printf("\n");
 
   printf("Введите начало и конец пути : ");    // пример : " 1 7 " : 1 - начало , 7 - конец пути 
   scanf ("%d %d",&S,&F);
 
   printf("\nВсе пути не пересекающиеся по ребрам : \n");
   PYTU();
   printf("Минимальный путь и его длина: ");
   GRAF(m);
 
 getch();
 return 0 ;
}

Ключевые слова: 
Графы . Кратчайшее расстояние . Путь .
ВложениеРазмер
GRAF(zadacha 4 a).rar12.82 кб