#include #include #include #define MAX_V 100 /*最大節點數*/ #define Infinite 1073741823 long int dist[MAX_V+1][MAX_V+1]; int path[MAX_V+1][MAX_V+1]; // 追蹤路徑的矩陣 int N; // 節點數量 int source, sink; // 起點和終點 void init(); bool floydWarshall(); void output_path(); void output_step(); void print_path(int start, int end); int main() { init(); // 檢查是否存在負權迴路 if (floydWarshall()) { printf("\n警告:圖形中存在負權迴路,計算結果可能不正確!\n"); output_step(); // output_path(); } else { output_path(); } return 0; } void init(){ FILE *fptr; int i, j, weight; fptr = fopen("shortestPath.dat", "r"); if (fptr == NULL) { perror("shortestPath.dat"); exit(1); } fscanf(fptr, "%d", &N); // 讀取圖形節點數 // 初始化距離矩陣與路徑矩陣 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; } } } while (fscanf(fptr, "%d %d %d", &i, &j, &weight) != EOF) { dist[i][j] = weight; path[i][j] = i; } fclose(fptr); printf("檔案內權重如下\n"); output_step(); printf("\n輸入起始節點 (1~%d): ", N); scanf("%d", &source); printf("輸入目標節點 (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]; // 主要的 Floyd-Warshall 演算法 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]; } } } } // 複製目前的距離矩陣 for (i = 1; i <= N; i++) { for (j = 1; j <= N; j++) { temp_dist[i][j] = dist[i][j]; } } // 再執行一次迭代來檢查負權迴路 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; // 找到負權迴路後直接跳出 } } } } end_check: return has_negative_cycle; } void print_path(int start, int end) { if (start == end) { printf("頂點%d", start); return; } if (path[start][end] == -1) { printf("無路徑"); return; } print_path(start, path[start][end]); printf(" → %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("∞\t"); else printf("%2ld\t", dist[i][j]); } printf("\n"); } } void output_path(){ int i, j; printf("\n節點間最短距離矩陣:\n"); output_step(); if (dist[source][sink] == Infinite) { printf("\n節點 V%d 到節點 V%d 沒有路徑\n", source, sink); } else { printf("\n從節點 V%d 到節點 V%d 的最短距離為:%ld\n", source, sink, dist[source][sink]); printf("最短路徑:"); print_path(source, sink); printf("\n"); } }