Data_Structure/作業/unit12/all-pairs-shortest-path-v1.c

136 lines
4.2 KiB
C
Raw Normal View History

2025-01-20 21:25:33 +08:00
/*
Program: all-pairs-shortest-path-v1.c (Report comments/bugs to chikh@yuntech.edu.tw)
Function: <EFBFBD><EFBFBD><EFBFBD>@Floyd-Warshall<EFBFBD>t<EFBFBD><EFBFBD><EFBFBD>k<EFBFBD>A<EFBFBD>H<EFBFBD>Ѫ<EFBFBD><EFBFBD><EFBFBD>shortestPath.dat<EFBFBD>ɮק@<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>J
Notes:
1) Floyd-Warshall<EFBFBD>t<EFBFBD><EFBFBD><EFBFBD>k<EFBFBD><EFBFBD><EFBFBD>u<EFBFBD>ʺA<EFBFBD>W<EFBFBD><EFBFBD><EFBFBD>v(dynamic programming)<EFBFBD>k
2) Ū<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʃҥε{<EFBFBD><EFBFBD><EFBFBD>X<EFBFBD><EFBFBD><EFBFBD>ۮѪ<EFBFBD><EFBFBD><EFBFBD>shortestPath.c<EFBFBD><EFBFBD><EFBFBD>վ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(prototype)<EFBFBD>B<EFBFBD>ץΥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܼ<EFBFBD>
3) <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѧ<EFBFBD> https://www.geeksforgeeks.org/floyd-warshall-algorithm-dp-16/
<EFBFBD>P https://www.programiz.com/dsa/floyd-warshall-algorithm
*/
#include <stdio.h>
#include <stdlib.h> /* for exit() */
#define MAX_V 100 /* <20>̤j<CCA4><6A><EFBFBD>I<EFBFBD><49> */
#define Inf 1073741823 /* <20><><EFBFBD><EFBFBD>2^30-1<><31><EFBFBD>j<EFBFBD>Ʀr<C6A6>A<EFBFBD><41><EFBFBD><EFBFBD><EFBFBD>{<7B><><EFBFBD><EFBFBD><EFBFBD>]<5D><><EFBFBD>L<EFBFBD><4C><EFBFBD>j<EFBFBD>ȡF<C8A1>i<EFBFBD><69><EFBFBD><EFBFBD>limits.h<>w<EFBFBD>q<EFBFBD><71>INT_MAX */
void init(int A[][MAX_V], int Y[][MAX_V], int *N) /* Ū<><C5AA><EFBFBD><EFBFBD><EFBFBD>J<EFBFBD><4A><EFBFBD><EFBFBD><EFBFBD>ɡB<C9A1>]<5D>w<EFBFBD>۾F<DBBE>x<EFBFBD>}<7D>A<EFBFBD><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5>c<EFBFBD>@<40><><EFBFBD>l<EFBFBD><6C> */
{
FILE *fptr;
int i, j;
int weight;
if ((fptr=fopen("shortestPath.dat","r")) == NULL) { /* <20>}<7D>Ҹ<EFBFBD><D2B8><EFBFBD><EFBFBD><EFBFBD> */
perror("shortestPath.dat");
exit(1);
}
fscanf(fptr,"%d",N); /* Ū<><C5AA><EFBFBD>ϧθ`<60>I<EFBFBD><49> */
for (i = 1; i <= *N; i++ )
for (j = 1; j <= *N; j++) {
A[i][j] = (i==j)? 0: Inf; /* <20><><EFBFBD>l<EFBFBD><6C>A[1..N][1..N]<5D>۾F<DBBE>x<EFBFBD>}<7D>A<EFBFBD>Ҧ<EFBFBD><D2A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>w<EFBFBD>]<5D><><EFBFBD><EFBFBD> */
Y[i][j] = (i==j)? i: -1;
}
while (fscanf(fptr,"%d %d %d",&i,&j,&weight) != EOF) {
A[i][j] = weight; /* Ū<><C5AA><EFBFBD>s<EFBFBD><73><EFBFBD><EFBFBD><EFBFBD>Ii<49>Pj<50><6A><EFBFBD><EFBFBD>v<EFBFBD><76><EFBFBD><EFBFBD> */
Y[i][j] = i; /* Y[i][j]<5D>w<EFBFBD>]<5D><>i */
}
fclose(fptr);
}
/* <20><><EFBFBD>UfloydWarshall()<29><EFBFBD>N<EFBFBD>C<EFBFBD>G<EFBFBD><47><EFBFBD>I(i,j)<29><><EFBFBD><EFBFBD><EFBFBD>p<EFBFBD><70><EFBFBD>̵u<CCB5>Z<EFBFBD><5A><EFBFBD>ȡA<C8A1>ðO<C3B0><4F><EFBFBD>i<EFBFBD>g<EFBFBD>ѭ<EFBFBD><D1AD>Ǥ<EFBFBD><C7A4>~<7E><><EFBFBD>I<EFBFBD>F<EFBFBD><46><EFBFBD>̵u */
void floydWarshall(int A[][MAX_V], int Y[][MAX_V], int N)
{
int i, j, k;
for (k = 1; k <= N; k++)
for (i = 1; i < N; i++)
for (j = 1; j <= N; j++)
if (A[i][k] + A[k][j] < A[i][j]) { //if (A[i][k] != Inf && A[k][j] != Inf && A[i][k] + A[k][j] < A[i][j]) {
A[i][j] = A[i][k] + A[k][j];
Y[i][j] = Y[k][j]; /* <20><><EFBFBD>g<EFBFBD><67> Y[i][j] = k */
}
/* <20>W<EFBFBD><57><EFBFBD>G<EFBFBD>hfor<6F>j<EFBFBD><6A><EFBFBD>Ω<EFBFBD><CEA9>ץ<EFBFBD><D7A5>C<EFBFBD>G<EFBFBD><47><EFBFBD>I(i,j)<29><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Z<EFBFBD><5A><EFBFBD>ȡA<C8A1>˵<EFBFBD><CBB5><EFBFBD><EFBFBD>_<EFBFBD>g<EFBFBD><67>k(<28><><EFBFBD>@<40>ӥi<D3A5><EFBFBD><E0AABA><EFBFBD>~<7E>I)<29><><EFBFBD>o<EFBFBD><6F><EFBFBD><EFBFBD><EFBFBD>p<EFBFBD>Z<EFBFBD><5A><EFBFBD><EFBFBD> */
/*
<EFBFBD>d<EFBFBD>Nline 53<EFBFBD><EFBFBD><EFBFBD>g<EFBFBD>k<EFBFBD>A<EFBFBD><EFBFBD><EFBFBD>g<EFBFBD><EFBFBD> Y[i][j] = k<EFBFBD>A<EFBFBD>P<EFBFBD>ǥi<EFBFBD>Ϥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>t<EFBFBD>O<EFBFBD><EFBFBD>?!
<EFBFBD>z<EFBFBD>ѡG<EFBFBD><EFBFBD>line 37<EFBFBD>i<EFBFBD><EFBFBD><EFBFBD>A<EFBFBD>Y<EFBFBD>G<EFBFBD><EFBFBD><EFBFBD>I(i,j)<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>s<EFBFBD>b<EFBFBD>A<EFBFBD>N<EFBFBD><EFBFBD>Y[i][j]<EFBFBD>w<EFBFBD>]<EFBFBD><EFBFBD>i<EFBFBD>C
<EFBFBD>]<EFBFBD><EFBFBD><EFBFBD>A<EFBFBD>bline 53<EFBFBD><EFBFBD><EFBFBD>A<EFBFBD>Yk<EFBFBD>Pj<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>s<EFBFBD>b<EFBFBD>A<EFBFBD>g<EFBFBD><EFBFBD>Y[k][j]<EFBFBD>P<EFBFBD>g<EFBFBD><EFBFBD>k<EFBFBD><EFBFBD><EFBFBD>N<EFBFBD>q<EFBFBD>ۦP<EFBFBD>A<EFBFBD>N<EFBFBD><EFBFBD><EFBFBD><EFBFBD>j<EFBFBD><EFBFBD><EFBFBD>e<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~<EFBFBD>I<EFBFBD><EFBFBD>k<EFBFBD>C
<EFBFBD><EFBFBD><EFBFBD>Yk<EFBFBD>Pj<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>L<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>s<EFBFBD><EFBFBD><EFBFBD>A<EFBFBD>h<EFBFBD>]Y[i][j] = Y[k][j]<EFBFBD>A<EFBFBD>N<EFBFBD><EFBFBD>i<EFBFBD><EFBFBD>j<EFBFBD><EFBFBD><EFBFBD>̫<EFBFBD><EFBFBD>@<EFBFBD>Ӥ<EFBFBD><EFBFBD>~<EFBFBD>I<EFBFBD>N<EFBFBD>ѱqk<EFBFBD><EFBFBD>j<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<EFBFBD>ҰO<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̫<EFBFBD>
<EFBFBD>@<EFBFBD>Ӥ<EFBFBD><EFBFBD>~<EFBFBD>I<EFBFBD>M<EFBFBD>w(Y[k][j]<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ثe<EFBFBD>Ҫ<EFBFBD>k<EFBFBD><EFBFBD>j<EFBFBD>Z<EFBFBD><EFBFBD>j<EFBFBD>̪񪺤<EFBFBD><EFBFBD>~<EFBFBD>I)<EFBFBD>C
<EFBFBD>z<EFBFBD>Lline 53<EFBFBD>]<EFBFBD>mY<EFBFBD>x<EFBFBD>}<EFBFBD><EFBFBD><EFBFBD>e<EFBFBD>A<EFBFBD>N<EFBFBD>i<EFBFBD>^<EFBFBD><EFBFBD><EFBFBD>o<EFBFBD><EFBFBD><EFBFBD>̵u<EFBFBD><EFBFBD><EFBFBD>|
*/
}
void printMatrix(int A[][MAX_V], int N)
{
int i, j;
printf("\n\n<EFBFBD>B<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>o<EFBFBD><EFBFBD><EFBFBD>I(i,j)<29><><EFBFBD><EFBFBD><EFBFBD>x<EFBFBD>}<7D><><EFBFBD>T<EFBFBD>p<EFBFBD>U<EFBFBD>G\n ");
for (i = 1; i <= N; i++) printf("%4d",i);
for (i = 0; i <= N; i++) printf("%4s",i==0? "\n +":"----");
for (i = 1; i <= N; i++) {
printf("\n<EFBFBD><EFBFBD><EFBFBD>I%d |",i);
for (j = 1; j <= N; j++) {
if (A[i][j] == Inf)
printf("%5s","<EFBFBD><EFBFBD>"); /* somewhat weird to use %5s instead of %4s here */
else
printf("%4d",A[i][j]);
}
//printf("\n");
}
}
int backtrack(int A[][MAX_V], int Y[][MAX_V], int source, int dest)
{
int distance, k = Y[source][dest]; /* k<><6B>source<63><65>dest<73><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~<7E><><EFBFBD>I */
if (source == dest) {
printf("<EFBFBD><EFBFBD><EFBFBD>I%d <20><>",source);
return A[source][dest];
}
if (Y[source][dest] == -1) {
printf("<EFBFBD><EFBFBD><EFBFBD>I%d<>P%d<><64><EFBFBD><EFBFBD><EFBFBD>S<EFBFBD><53><EFBFBD><EFBFBD><EFBFBD>|<7C>s<EFBFBD>b:( ",source,dest);
return Inf;
}
distance = backtrack(A,Y,source,k);
printf(" %d <20><>",dest);
return distance+A[k][dest];
}
void traverseMatrix(int A[][MAX_V],int Y[][MAX_V])
{
int distance, source, sink;
printf("\n\n<EFBFBD>d<EFBFBD>ߥ<EFBFBD><EFBFBD>G<EFBFBD>I<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̵u<EFBFBD><EFBFBD><EFBFBD>|\n<EFBFBD><EFBFBD><EFBFBD>I(0<>h<EFBFBD>X<EFBFBD>d<EFBFBD><64>) => ");
scanf("%d",&source);
if (source == 0) return;
printf("<EFBFBD><EFBFBD><EFBFBD>I(0<>h<EFBFBD>X<EFBFBD>d<EFBFBD><64>) => ");
scanf("%d",&sink);
if (sink == 0) return;
printf("<EFBFBD>̵u<EFBFBD><EFBFBD><EFBFBD>|<7C>G");
distance = backtrack(A,Y,source,sink);
printf("\b\b (<28>Ҹg<D2B8><67><EFBFBD><EFBFBD><EFBFBD>Z<EFBFBD><5A><EFBFBD>`<60>M=%d)(<28>d<EFBFBD><64>A[%d][%d]=%d)",distance,source,sink,A[source][sink]); /* <20>ٰ<EFBFBD><D9B0>̫<EFBFBD><CCAB><EFBFBD><EFBFBD>ܦh<DCA6>l<EFBFBD><6C>"<22><>" */
}
int main()
{
int N, A[MAX_V][MAX_V], Y[MAX_V][MAX_V] = {0};
/* N<><4E><EFBFBD>ϩҧt<D2A7><74><EFBFBD><EFBFBD><EFBFBD>I<EFBFBD><49><EFBFBD><EFBFBD><EFBFBD>`<60>ơFA[1..N][1..N]<5D><><EFBFBD>ϧΪ<CFA7><CEAA>۾F<DBBE>x<EFBFBD>} */
/* Y[1..N][1..N]<5D>O<EFBFBD><4F><EFBFBD><EFBFBD><EFBFBD>G<EFBFBD><47><EFBFBD>I(i,j)<29><><EFBFBD><EFBFBD><EFBFBD>Zj<5A>̪񪺤<CCAA><F1AABAA4>~<7E>I<EFBFBD>A<EFBFBD>N<EFBFBD>Ω<EFBFBD><CEA9>̵u<CCB5><75><EFBFBD>|<7C>^<5E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
printf("\n*** <20><> all-pairs shortest-path <20><><EFBFBD>D ***");
init(A,Y,&N); /* Ū<><C5AA><EFBFBD><EFBFBD><EFBFBD>J<EFBFBD><4A><EFBFBD><EFBFBD><EFBFBD>ɡB<C9A1>]<5D>w<EFBFBD>۾F<DBBE>x<EFBFBD>}<7D>A<EFBFBD>ç<EFBFBD><C3A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5>c<EFBFBD>@<40><><EFBFBD>l<EFBFBD><6C> */
floydWarshall(A,Y,N);
printMatrix(A,N);
//printMatrix(Y,N);
traverseMatrix(A,Y);
return 0;
}