187 lines
4.3 KiB
C++
187 lines
4.3 KiB
C++
|
#include <stdio.h>
|
|||
|
#include <stdlib.h>
|
|||
|
#include <stdbool.h>
|
|||
|
|
|||
|
#define MAX_V 100 /*<2A>̤j<CCA4>`<60>I<EFBFBD><49>*/
|
|||
|
#define Infinite 1073741823
|
|||
|
|
|||
|
long int dist[MAX_V+1][MAX_V+1];
|
|||
|
int path[MAX_V+1][MAX_V+1]; // <20>l<EFBFBD>ܸ<EFBFBD><DCB8>|<7C><><EFBFBD>x<EFBFBD>}
|
|||
|
int N; // <20>`<60>I<EFBFBD>ƶq
|
|||
|
int source, sink; // <20>_<EFBFBD>I<EFBFBD>M<EFBFBD><4D><EFBFBD>I
|
|||
|
|
|||
|
void init();
|
|||
|
bool floydWarshall();
|
|||
|
void output_path();
|
|||
|
void output_step();
|
|||
|
void print_path(int start, int end);
|
|||
|
|
|||
|
int main() {
|
|||
|
init();
|
|||
|
|
|||
|
// <20>ˬd<CBAC>O<EFBFBD>_<EFBFBD>s<EFBFBD>b<EFBFBD>t<EFBFBD>v<EFBFBD>j<EFBFBD><6A>
|
|||
|
if (floydWarshall()) {
|
|||
|
printf("\nĵ<EFBFBD>i<EFBFBD>G<EFBFBD>ϧΤ<EFBFBD><EFBFBD>s<EFBFBD>b<EFBFBD>t<EFBFBD>v<EFBFBD>j<EFBFBD><EFBFBD><EFBFBD>A<EFBFBD>p<EFBFBD><EFBFBD>G<EFBFBD>i<EFBFBD>ण<EFBFBD><EFBFBD><EFBFBD>T<EFBFBD>I\n");
|
|||
|
output_path();
|
|||
|
} else {
|
|||
|
output_path();
|
|||
|
}
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
void init(){
|
|||
|
FILE *fptr;
|
|||
|
int i, j, weight,line_count=0;
|
|||
|
char line[256];
|
|||
|
|
|||
|
fptr = fopen("shortestPath_down_1.dat", "r");
|
|||
|
if (fptr == NULL) {
|
|||
|
perror("shortestPath_up_1.dat");
|
|||
|
exit(1);
|
|||
|
}
|
|||
|
|
|||
|
// <20>p<EFBFBD><70><EFBFBD>`<60><><EFBFBD>I<EFBFBD><49>
|
|||
|
while (fgets(line, sizeof(line), fptr)) {
|
|||
|
line_count++;
|
|||
|
}
|
|||
|
N = line_count;
|
|||
|
rewind(fptr);
|
|||
|
|
|||
|
// <20><><EFBFBD>l<EFBFBD>ƶZ<C6B6><5A><EFBFBD>x<EFBFBD>}<7D>P<EFBFBD><50><EFBFBD>|<7C>x<EFBFBD>}
|
|||
|
for (i = 1; i <= N; i++) {
|
|||
|
for (j = 1; j <= N; j++) {
|
|||
|
if (i == j) {
|
|||
|
dist[i][j] = 0;
|
|||
|
path[i][j] = i;
|
|||
|
} else {
|
|||
|
dist[i][j] = Infinite;
|
|||
|
path[i][j] = -1;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Ū<><C5AA><EFBFBD>U<EFBFBD>T<EFBFBD><54><EFBFBD>x<EFBFBD>}
|
|||
|
for (i = 1; i <= N; i++) {
|
|||
|
for (j = 1; j < i; j++) {
|
|||
|
if (fscanf(fptr, "%d", &weight) == 1) {
|
|||
|
if (weight != 0) { // <20>u<EFBFBD>B<EFBFBD>z<EFBFBD>D<EFBFBD>s<EFBFBD>v<EFBFBD><76>
|
|||
|
dist[i][j] = weight;
|
|||
|
path[i][j] = i;
|
|||
|
// <20>]<5D><><EFBFBD>O<EFBFBD>L<EFBFBD>V<EFBFBD>ϡA<CFA1>ҥH<D2A5><48><EFBFBD>٦<EFBFBD><D9A6>m<EFBFBD>]<5D>n<EFBFBD>]<5D>w
|
|||
|
if (i != j) {
|
|||
|
dist[j][i] = weight;
|
|||
|
path[j][i] = j;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
// <20><><EFBFBD>L<EFBFBD>Ӧ<EFBFBD><D3A6>Ѿl<D1BE><6C><EFBFBD>r<EFBFBD><72>
|
|||
|
fgets(line, sizeof(line), fptr);
|
|||
|
}
|
|||
|
|
|||
|
fclose(fptr);
|
|||
|
printf("<EFBFBD>ɮפ<EFBFBD><EFBFBD>v<EFBFBD><EFBFBD><EFBFBD>p<EFBFBD>U\n");
|
|||
|
output_step();
|
|||
|
|
|||
|
printf("\n<EFBFBD><EFBFBD><EFBFBD>J<EFBFBD>_<EFBFBD>l<EFBFBD>`<60>I (1~%d): ", N);
|
|||
|
scanf("%d", &source);
|
|||
|
printf("<EFBFBD><EFBFBD><EFBFBD>J<EFBFBD>ؼи`<60>I (1~%d): ", N);
|
|||
|
scanf("%d", &sink);
|
|||
|
}
|
|||
|
|
|||
|
bool floydWarshall(){
|
|||
|
int k, i, j;
|
|||
|
bool has_negative_cycle = false;
|
|||
|
long int temp_dist[MAX_V+1][MAX_V+1];
|
|||
|
|
|||
|
// <20>D<EFBFBD>n<EFBFBD><6E> Floyd-Warshall <20>t<EFBFBD><74><EFBFBD>k
|
|||
|
for (k = 1; k <= N; k++) {
|
|||
|
for (i = 1; i <= N; i++) {
|
|||
|
for (j = 1; j <= N; j++) {
|
|||
|
if (dist[i][k] != Infinite &&
|
|||
|
dist[k][j] != Infinite &&
|
|||
|
dist[i][k] + dist[k][j] < dist[i][j]) {
|
|||
|
dist[i][j] = dist[i][k] + dist[k][j];
|
|||
|
path[i][j] = path[k][j];
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// <20>ƻs<C6BB>ثe<D8AB><65><EFBFBD>Z<EFBFBD><5A><EFBFBD>x<EFBFBD>}
|
|||
|
for (i = 1; i <= N; i++) {
|
|||
|
for (j = 1; j <= N; j++) {
|
|||
|
temp_dist[i][j] = dist[i][j];
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// <20>A<EFBFBD><41><EFBFBD><EFBFBD><EFBFBD>@<40><><EFBFBD><EFBFBD><EFBFBD>N<EFBFBD><4E><EFBFBD>ˬd<CBAC>t<EFBFBD>v<EFBFBD>j<EFBFBD><6A>
|
|||
|
for (k = 1; k <= N; k++) {
|
|||
|
for (i = 1; i <= N; i++) {
|
|||
|
for (j = 1; j <= N; j++) {
|
|||
|
if (dist[i][k] != Infinite &&
|
|||
|
dist[k][j] != Infinite &&
|
|||
|
dist[i][k] + dist[k][j] < temp_dist[i][j]) {
|
|||
|
has_negative_cycle = true;
|
|||
|
goto end_check; // <20><><EFBFBD><EFBFBD><EFBFBD>t<EFBFBD>v<EFBFBD>j<EFBFBD><6A><EFBFBD>᪽<EFBFBD><E1AABD><EFBFBD><EFBFBD><EFBFBD>X
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
end_check:
|
|||
|
return has_negative_cycle;
|
|||
|
}
|
|||
|
|
|||
|
void print_path(int start, int end) {
|
|||
|
if (start == end) {
|
|||
|
printf("<EFBFBD><EFBFBD><EFBFBD>I%d", start);
|
|||
|
return;
|
|||
|
}
|
|||
|
if (path[start][end] == -1) {
|
|||
|
printf("<EFBFBD>L<EFBFBD><EFBFBD><EFBFBD>|");
|
|||
|
return;
|
|||
|
}
|
|||
|
print_path(start, path[start][end]);
|
|||
|
printf(" <20><> %d", end);
|
|||
|
}
|
|||
|
|
|||
|
void output_step(){
|
|||
|
int i, j;
|
|||
|
|
|||
|
printf("\t");
|
|||
|
for (j = 1; j <= N; j++) {
|
|||
|
printf("V%d\t", j);
|
|||
|
}
|
|||
|
printf("\n");
|
|||
|
|
|||
|
for (i = 1; i <= N; i++) {
|
|||
|
printf("V%d\t", i);
|
|||
|
for (j = 1; j <= N; j++) {
|
|||
|
if (dist[i][j] == Infinite)
|
|||
|
printf("<EFBFBD><EFBFBD>\t");
|
|||
|
else
|
|||
|
printf("%2ld\t", dist[i][j]);
|
|||
|
}
|
|||
|
printf("\n");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void output_path(){
|
|||
|
int i, j;
|
|||
|
|
|||
|
printf("\n<EFBFBD>`<60>I<EFBFBD><49><EFBFBD>̵u<CCB5>Z<EFBFBD><5A><EFBFBD>x<EFBFBD>}<7D>G\n");
|
|||
|
output_step();
|
|||
|
|
|||
|
if (dist[source][sink] == Infinite) {
|
|||
|
printf("\n<EFBFBD>`<60>I V%d <20><><EFBFBD>`<60>I V%d <20>S<EFBFBD><53><EFBFBD><EFBFBD><EFBFBD>|\n", source, sink);
|
|||
|
} else {
|
|||
|
printf("\n<EFBFBD>q<EFBFBD>`<60>I V%d <20><><EFBFBD>`<60>I V%d <20><><EFBFBD>̵u<CCB5>Z<EFBFBD><5A><EFBFBD><EFBFBD><EFBFBD>G%ld\n",
|
|||
|
source, sink, dist[source][sink]);
|
|||
|
printf("<EFBFBD>̵u<EFBFBD><EFBFBD><EFBFBD>|<7C>G");
|
|||
|
print_path(source, sink);
|
|||
|
printf("\n");
|
|||
|
}
|
|||
|
}
|