diff --git a/.vscode/settings.json b/.vscode/settings.json index 7b08d16..c10c8c7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,7 +4,7 @@ "C_Cpp_Runner.debuggerPath": "gdb", "C_Cpp_Runner.cStandard": "c17", "C_Cpp_Runner.cppStandard": "c++17", - "C_Cpp_Runner.msvcBatchPath": "C:/Program Files/Microsoft Visual Studio/VR_NR/Community/VC/Auxiliary/Build/vcvarsall.bat", + "C_Cpp_Runner.msvcBatchPath": "", "C_Cpp_Runner.useMsvc": false, "C_Cpp_Runner.warnings": [ "-Wall", diff --git a/exercise/44.c b/exercise/44.c index 516b889..7659a53 100644 --- a/exercise/44.c +++ b/exercise/44.c @@ -1,11 +1,81 @@ #include #include +#include #ifdef _WIN32 #include #endif +// 邻接矩阵存储图 +typedef struct +{ + int vexnum; + int **arcs; +} AMGraphStruct; +typedef AMGraphStruct *AMGraph; + +// 定义最大顶点数和最大边权值 +#define MaxInt 0x3f3f3f3f +#define MAXN 1005 // 最大顶点数 +static bool S[MAXN]; // S[i]为true表示顶点i已加入集合S,否则未加入 +static int D[MAXN]; // D[i]为v0到顶点i的当前最短路径长度 +static int Path[MAXN]; // Path[i]为v0到顶点i的最短路径上的前驱顶点 + +// Dijkstra算法求最短路径 +void ShortestPath_DIJ(AMGraph G, int v0) +{ + // 初始化 + int n, i, v, w; // n为顶点数,i为循环变量,v为当前顶点,w为邻接顶点 + int min; + n = G->vexnum; + for (v = 0; v < n; ++v) + { + S[v] = false; + D[v] = G->arcs[v0][v]; + if (D[v] < MaxInt) + { + Path[v] = v0; + } + else + { + Path[v] = -1; + } + } + S[v0] = true; + D[v0] = 0; + + // 主循环,每次求得v0到某个顶点的最短路径,并将该顶点加入集合S + for (i = 1; i < n; ++i) + { + // 在V-S中选择距离v0最近的顶点u + min = MaxInt; + for (w = 0; w < n; ++w) + { + if (!S[w] && D[w] < min) + { + v = w; + min = D[w]; + } + } + + // 如果min为MaxInt,说明v0到其他顶点的路径都不可达 + if (min == MaxInt) + { + break; + } + S[v] = true; + + // 修改当前最短路径及距离 + for (w = 0; w < n; ++w) + { + if (!S[w] && (D[v] + G->arcs[v][w] < D[w])) + { + D[w] = D[v] + G->arcs[v][w]; + Path[w] = v; + } + } + } +} -// Dijkstra int main(void) { #ifdef _WIN32 @@ -14,6 +84,75 @@ int main(void) SetConsoleCP(65001); #endif + // 输入顶点数和边数 + int n, m; + if (scanf("%d %d", &n, &m) != 2) + { + return 0; + } + if (n < 1 || n > MAXN || m < 0) + { + printf("参数不符合要求\n"); + return 0; + } + + // 初始化邻接矩阵 + AMGraph g = (AMGraph)malloc(sizeof(*g)); + g->vexnum = n; + g->arcs = (int **)malloc((size_t)n * sizeof(int *)); + for (int i = 0; i < n; ++i) + { + g->arcs[i] = (int *)malloc((size_t)n * sizeof(int)); + for (int j = 0; j < n; ++j) + { + g->arcs[i][j] = (i == j) ? 0 : MaxInt; + } + } + + // 输入边信息 + for (int i = 0; i < m; ++i) + { + int x, y, z; + if (scanf("%d %d %d", &x, &y, &z) != 3) + { + for (int k = 0; k < n; ++k) free(g->arcs[k]); + free(g->arcs); + free(g); + printf("参数不符合要求\n"); + return 0; + } + if (x < 1 || x > n || y < 1 || y > n || z <= 0 || z > 10000) + { + for (int k = 0; k < n; ++k) free(g->arcs[k]); + free(g->arcs); + free(g); + printf("参数不符合要求\n"); + return 0; + } + if (z < g->arcs[x - 1][y - 1]) + { + g->arcs[x - 1][y - 1] = z; + } + } + + // 执行Dijkstra算法 + ShortestPath_DIJ(g, 0); + if (D[n - 1] >= MaxInt) + { + printf("-1\n"); + } + else + { + printf("%d\n", D[n - 1]); + } + + // 释放内存 + for (int i = 0; i < n; ++i) + { + free(g->arcs[i]); + } + free(g->arcs); + free(g); return 0; } \ No newline at end of file diff --git a/exercise/44.exe b/exercise/44.exe new file mode 100644 index 0000000..d48f4e8 Binary files /dev/null and b/exercise/44.exe differ