跳转至

第6章 图代码

使用建议

  • 先配合对应章节阅读:第6章 图 正文
  • 这一页优先提供站内可直接查看的代码版本,适合网页阅读和搜索。
  • 这一页主要用于网页阅读,建议结合对应正文与逐行注释版一起使用。

文件位置

  • 普通代码版:第6章普通代码版
  • 逐行注释版:第6章逐行注释版代码
  • 兼容编码版:第6章兼容编码版逐行注释代码

普通代码版

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_VERTEX_NUM 20
#define INF 1000000000

/* 邻接矩阵图结构:vexs 保存顶点名,edges 保存边权,vexnum/arcnum 记录规模。 */
typedef struct {
    char vexs[MAX_VERTEX_NUM];
    int edges[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
    int vexnum;
    int arcnum;
    bool directed;
} AMGraph;

/* 邻接表边结点:adjvex 是邻接点下标,weight 是边权,nextarc 指向下一条边。 */
typedef struct ArcNode {
    int adjvex;
    int weight;
    struct ArcNode *nextarc;
} ArcNode;

/* 邻接表顶点结点:data 保存顶点名,firstarc 指向第一条出边。 */
typedef struct {
    char data;
    ArcNode *firstarc;
} VNode;

/* 邻接表图结构:vertices 保存所有顶点,vexnum/arcnum 记录规模。 */
typedef struct {
    VNode vertices[MAX_VERTEX_NUM];
    int vexnum;
    int arcnum;
    bool directed;
} ALGraph;

/* 顺序队列:BFS 需要用它实现“先发现的顶点先扩展”。 */
typedef struct {
    int data[MAX_VERTEX_NUM];
    int front;
    int rear;
} SqQueue;

/* Kruskal 用的边结构:把邻接矩阵中的有效边提出来,后面统一按权值排序。 */
typedef struct {
    int u;
    int v;
    int weight;
} Edge;

/* 初始化队列:front 和 rear 都回到 0,表示当前为空。 */
void InitQueue(SqQueue *queue) {
    if (queue == NULL) {
        return;
    }

    queue->front = 0;
    queue->rear = 0;
}

/* 判断队列是否为空:front 和 rear 重合时表示没有元素。 */
bool IsQueueEmpty(const SqQueue *queue) {
    return queue == NULL || queue->front == queue->rear;
}

/* 入队:把顶点下标压到队尾,供后续按 BFS 顺序处理。 */
bool Enqueue(SqQueue *queue, int value) {
    int next_rear;

    if (queue == NULL) {
        return false;
    }

    next_rear = (queue->rear + 1) % MAX_VERTEX_NUM;
    if (next_rear == queue->front) {
        return false;
    }

    queue->data[queue->rear] = value;
    queue->rear = next_rear;
    return true;
}

/* 出队:取出当前队头顶点下标,并让 front 向后移动。 */
bool Dequeue(SqQueue *queue, int *value) {
    if (queue == NULL || value == NULL || IsQueueEmpty(queue)) {
        return false;
    }

    *value = queue->data[queue->front];
    queue->front = (queue->front + 1) % MAX_VERTEX_NUM;
    return true;
}

/* 初始化邻接矩阵:先清规模,再把矩阵设置成“无边”状态。 */
void InitAMGraph(AMGraph *graph, const char *vertex_names, bool directed) {
    int i;
    int j;
    int length;

    if (graph == NULL || vertex_names == NULL) {
        return;
    }

    length = (int)strlen(vertex_names);
    if (length <= 0 || length > MAX_VERTEX_NUM) {
        return;
    }

    graph->vexnum = length;
    graph->arcnum = 0;
    graph->directed = directed;

    for (i = 0; i < graph->vexnum; i++) {
        graph->vexs[i] = vertex_names[i];
    }

    for (i = 0; i < graph->vexnum; i++) {
        for (j = 0; j < graph->vexnum; j++) {
            if (i == j) {
                graph->edges[i][j] = 0;
            } else {
                graph->edges[i][j] = INF;
            }
        }
    }
}

/* 按顶点名定位下标:后续加边和遍历都依赖这个映射。 */
int LocateVertexAM(const AMGraph *graph, char vertex) {
    int i;

    if (graph == NULL) {
        return -1;
    }

    for (i = 0; i < graph->vexnum; i++) {
        if (graph->vexs[i] == vertex) {
            return i;
        }
    }

    return -1;
}

/* 邻接矩阵加边:有向图只加一侧,无向图要对称补上另一侧。 */
bool AddEdgeAM(AMGraph *graph, char from, char to, int weight) {
    int i;
    int j;

    if (graph == NULL || weight <= 0) {
        return false;
    }

    i = LocateVertexAM(graph, from);
    j = LocateVertexAM(graph, to);
    if (i < 0 || j < 0 || i == j) {
        return false;
    }

    if (graph->edges[i][j] == INF) {
        graph->arcnum++;
    }

    graph->edges[i][j] = weight;
    if (!graph->directed) {
        graph->edges[j][i] = weight;
    }

    return true;
}

/* 打印邻接矩阵:便于把“图结构”和“矩阵内容”对应起来。 */
void PrintAMGraph(const AMGraph *graph) {
    int i;
    int j;

    if (graph == NULL) {
        return;
    }

    printf("Adjacency Matrix:\n   ");
    for (i = 0; i < graph->vexnum; i++) {
        printf("  %c", graph->vexs[i]);
    }
    printf("\n");

    for (i = 0; i < graph->vexnum; i++) {
        printf(" %c ", graph->vexs[i]);
        for (j = 0; j < graph->vexnum; j++) {
            if (graph->edges[i][j] == INF) {
                printf("  -");
            } else {
                printf(" %2d", graph->edges[i][j]);
            }
        }
        printf("\n");
    }
}

/* 创建邻接表边结点:把邻接点和权值封装起来。 */
ArcNode *CreateArcNode(int adjvex, int weight) {
    ArcNode *node;

    node = (ArcNode *)malloc(sizeof(ArcNode));
    if (node == NULL) {
        return NULL;
    }

    node->adjvex = adjvex;
    node->weight = weight;
    node->nextarc = NULL;
    return node;
}

/* 初始化邻接表:先写顶点,再把每个顶点的第一条边指针置空。 */
void InitALGraph(ALGraph *graph, const char *vertex_names, bool directed) {
    int i;
    int length;

    if (graph == NULL || vertex_names == NULL) {
        return;
    }

    length = (int)strlen(vertex_names);
    if (length <= 0 || length > MAX_VERTEX_NUM) {
        return;
    }

    graph->vexnum = length;
    graph->arcnum = 0;
    graph->directed = directed;

    for (i = 0; i < graph->vexnum; i++) {
        graph->vertices[i].data = vertex_names[i];
        graph->vertices[i].firstarc = NULL;
    }
}

/* 按顶点名定位邻接表下标:和邻接矩阵版本保持相同思路。 */
int LocateVertexAL(const ALGraph *graph, char vertex) {
    int i;

    if (graph == NULL) {
        return -1;
    }

    for (i = 0; i < graph->vexnum; i++) {
        if (graph->vertices[i].data == vertex) {
            return i;
        }
    }

    return -1;
}

/* 头插法挂一条边:新边结点插到邻接表最前面。 */
bool AddArcNode(ALGraph *graph, int from, int to, int weight) {
    ArcNode *node;

    if (graph == NULL || from < 0 || from >= graph->vexnum || to < 0 || to >= graph->vexnum) {
        return false;
    }

    node = CreateArcNode(to, weight);
    if (node == NULL) {
        return false;
    }

    node->nextarc = graph->vertices[from].firstarc;
    graph->vertices[from].firstarc = node;
    return true;
}

/* 邻接表加边:无向图要补两次,有向图只补一次。 */
bool AddEdgeAL(ALGraph *graph, char from, char to, int weight) {
    int i;
    int j;

    if (graph == NULL || weight <= 0) {
        return false;
    }

    i = LocateVertexAL(graph, from);
    j = LocateVertexAL(graph, to);
    if (i < 0 || j < 0 || i == j) {
        return false;
    }

    if (!AddArcNode(graph, i, j, weight)) {
        return false;
    }

    if (!graph->directed) {
        if (!AddArcNode(graph, j, i, weight)) {
            return false;
        }
    }

    graph->arcnum++;
    return true;
}

/* 打印邻接表:观察每个顶点后面都连了哪些邻接点。 */
void PrintALGraph(const ALGraph *graph) {
    int i;
    ArcNode *arc;

    if (graph == NULL) {
        return;
    }

    printf("Adjacency List:\n");
    for (i = 0; i < graph->vexnum; i++) {
        printf("%c -> ", graph->vertices[i].data);
        arc = graph->vertices[i].firstarc;
        while (arc != NULL) {
            printf("(%c, w=%d) ", graph->vertices[arc->adjvex].data, arc->weight);
            arc = arc->nextarc;
        }
        printf("^\n");
    }
}

/* 释放邻接表:逐个顶点把边链表清掉,避免内存泄漏。 */
void DestroyALGraph(ALGraph *graph) {
    int i;
    ArcNode *current;
    ArcNode *next;

    if (graph == NULL) {
        return;
    }

    for (i = 0; i < graph->vexnum; i++) {
        current = graph->vertices[i].firstarc;
        while (current != NULL) {
            next = current->nextarc;
            free(current);
            current = next;
        }
        graph->vertices[i].firstarc = NULL;
    }
}

/* 访问顶点:统一输出接口,后续遍历都复用它。 */
void VisitVertex(char vertex) {
    printf("%c ", vertex);
}

/* 邻接矩阵版 DFS 递归函数:先访问当前顶点,再递归访问尚未访问的邻接点。 */
void DFSAMUtil(const AMGraph *graph, int v, bool visited[]) {
    int w;

    visited[v] = true;
    VisitVertex(graph->vexs[v]);

    for (w = 0; w < graph->vexnum; w++) {
        if (!visited[w] && graph->edges[v][w] != INF && graph->edges[v][w] != 0) {
            DFSAMUtil(graph, w, visited);
        }
    }
}

/* 邻接矩阵版 DFS:兼顾非连通图,必要时从新的连通分量重新出发。 */
void DFSAM(const AMGraph *graph) {
    bool visited[MAX_VERTEX_NUM] = {false};
    int i;

    if (graph == NULL) {
        return;
    }

    for (i = 0; i < graph->vexnum; i++) {
        if (!visited[i]) {
            DFSAMUtil(graph, i, visited);
        }
    }
}

/* 邻接矩阵版 BFS:先访问一个顶点,再按队列顺序逐层扩展。 */
void BFSAM(const AMGraph *graph) {
    bool visited[MAX_VERTEX_NUM] = {false};
    SqQueue queue;
    int i;
    int v;
    int w;

    if (graph == NULL) {
        return;
    }

    InitQueue(&queue);

    for (i = 0; i < graph->vexnum; i++) {
        if (visited[i]) {
            continue;
        }

        visited[i] = true;
        VisitVertex(graph->vexs[i]);
        Enqueue(&queue, i);

        while (!IsQueueEmpty(&queue)) {
            Dequeue(&queue, &v);
            for (w = 0; w < graph->vexnum; w++) {
                if (!visited[w] && graph->edges[v][w] != INF && graph->edges[v][w] != 0) {
                    visited[w] = true;
                    VisitVertex(graph->vexs[w]);
                    Enqueue(&queue, w);
                }
            }
        }
    }
}

/* 邻接表版 DFS 递归函数:顺着边链表把当前顶点能到的点一路走深。 */
void DFSALUtil(const ALGraph *graph, int v, bool visited[]) {
    ArcNode *arc;

    visited[v] = true;
    VisitVertex(graph->vertices[v].data);

    arc = graph->vertices[v].firstarc;
    while (arc != NULL) {
        if (!visited[arc->adjvex]) {
            DFSALUtil(graph, arc->adjvex, visited);
        }
        arc = arc->nextarc;
    }
}

/* 邻接表版 DFS:写法和矩阵版类似,只是邻接点获取方式不同。 */
void DFSAL(const ALGraph *graph) {
    bool visited[MAX_VERTEX_NUM] = {false};
    int i;

    if (graph == NULL) {
        return;
    }

    for (i = 0; i < graph->vexnum; i++) {
        if (!visited[i]) {
            DFSALUtil(graph, i, visited);
        }
    }
}

/* 邻接表版 BFS:队列逻辑不变,只是遍历邻接点时改成扫边链表。 */
void BFSAL(const ALGraph *graph) {
    bool visited[MAX_VERTEX_NUM] = {false};
    SqQueue queue;
    ArcNode *arc;
    int i;
    int v;

    if (graph == NULL) {
        return;
    }

    InitQueue(&queue);

    for (i = 0; i < graph->vexnum; i++) {
        if (visited[i]) {
            continue;
        }

        visited[i] = true;
        VisitVertex(graph->vertices[i].data);
        Enqueue(&queue, i);

        while (!IsQueueEmpty(&queue)) {
            Dequeue(&queue, &v);
            arc = graph->vertices[v].firstarc;
            while (arc != NULL) {
                if (!visited[arc->adjvex]) {
                    visited[arc->adjvex] = true;
                    VisitVertex(graph->vertices[arc->adjvex].data);
                    Enqueue(&queue, arc->adjvex);
                }
                arc = arc->nextarc;
            }
        }
    }
}

/* 只做标记不输出的 DFS:后面统计连通分量时更方便复用。 */
void DFSMarkAM(const AMGraph *graph, int v, bool visited[]) {
    int w;

    visited[v] = true;
    for (w = 0; w < graph->vexnum; w++) {
        if (!visited[w] && graph->edges[v][w] != INF && graph->edges[v][w] != 0) {
            DFSMarkAM(graph, w, visited);
        }
    }
}

/* 统计无向图连通分量:每发现一个还没访问过的顶点,就说明找到一个新分量。 */
int CountConnectedComponentsAM(const AMGraph *graph) {
    bool visited[MAX_VERTEX_NUM] = {false};
    int components;
    int i;

    if (graph == NULL) {
        return 0;
    }

    components = 0;
    for (i = 0; i < graph->vexnum; i++) {
        if (!visited[i]) {
            components++;
            DFSMarkAM(graph, i, visited);
        }
    }

    return components;
}

/* 拓扑排序:不断取入度为 0 的顶点输出,并删除其发出的边。 */
bool TopologicalSortAL(const ALGraph *graph, char order[]) {
    int indegree[MAX_VERTEX_NUM] = {0};
    SqQueue queue;
    ArcNode *arc;
    int i;
    int v;
    int count;

    if (graph == NULL || order == NULL) {
        return false;
    }

    for (i = 0; i < graph->vexnum; i++) {
        arc = graph->vertices[i].firstarc;
        while (arc != NULL) {
            indegree[arc->adjvex]++;
            arc = arc->nextarc;
        }
    }

    InitQueue(&queue);
    for (i = 0; i < graph->vexnum; i++) {
        if (indegree[i] == 0) {
            Enqueue(&queue, i);
        }
    }

    count = 0;
    while (!IsQueueEmpty(&queue)) {
        Dequeue(&queue, &v);
        order[count++] = graph->vertices[v].data;

        arc = graph->vertices[v].firstarc;
        while (arc != NULL) {
            indegree[arc->adjvex]--;
            if (indegree[arc->adjvex] == 0) {
                Enqueue(&queue, arc->adjvex);
            }
            arc = arc->nextarc;
        }
    }

    order[count] = '\0';
    return count == graph->vexnum;
}

/* 求并查集根结点:一路向上找代表元,并顺手做路径压缩。 */
int FindSet(int parent[], int x) {
    if (parent[x] != x) {
        parent[x] = FindSet(parent, parent[x]);
    }
    return parent[x];
}

/* 合并两个集合:把秩较小的树挂到秩较大的树下面,减少后续查找高度。 */
void UnionSet(int parent[], int rank[], int x, int y) {
    int root_x;
    int root_y;

    root_x = FindSet(parent, x);
    root_y = FindSet(parent, y);
    if (root_x == root_y) {
        return;
    }

    if (rank[root_x] < rank[root_y]) {
        parent[root_x] = root_y;
    } else if (rank[root_x] > rank[root_y]) {
        parent[root_y] = root_x;
    } else {
        parent[root_y] = root_x;
        rank[root_x]++;
    }
}

/* 给 qsort 用的比较函数:边权更小的边排在前面,方便 Kruskal 逐条尝试。 */
int CompareEdgeByWeight(const void *lhs, const void *rhs) {
    const Edge *left;
    const Edge *right;

    left = (const Edge *)lhs;
    right = (const Edge *)rhs;
    return left->weight - right->weight;
}

/* Kruskal 算法:把所有边按权值从小到大尝试,能接且不成环就选中。 */
int KruskalMSTWeightAM(const AMGraph *graph) {
    Edge edges[MAX_VERTEX_NUM * MAX_VERTEX_NUM];
    int parent[MAX_VERTEX_NUM];
    int rank[MAX_VERTEX_NUM] = {0};
    int edge_count;
    int selected_edges;
    int total_weight;
    int i;
    int j;

    if (graph == NULL || graph->directed || graph->vexnum == 0) {
        return -1;
    }

    edge_count = 0;
    for (i = 0; i < graph->vexnum; i++) {
        parent[i] = i;
        for (j = i + 1; j < graph->vexnum; j++) {
            if (graph->edges[i][j] != INF && graph->edges[i][j] != 0) {
                edges[edge_count].u = i;
                edges[edge_count].v = j;
                edges[edge_count].weight = graph->edges[i][j];
                edge_count++;
            }
        }
    }

    qsort(edges, edge_count, sizeof(Edge), CompareEdgeByWeight);

    total_weight = 0;
    selected_edges = 0;
    for (i = 0; i < edge_count && selected_edges < graph->vexnum - 1; i++) {
        if (FindSet(parent, edges[i].u) != FindSet(parent, edges[i].v)) {
            UnionSet(parent, rank, edges[i].u, edges[i].v);
            total_weight += edges[i].weight;
            selected_edges++;
        }
    }

    if (selected_edges != graph->vexnum - 1) {
        return -1;
    }

    return total_weight;
}

/* Prim 算法求最小生成树权值:每次把当前生成树到外部的最短边接进来。 */
int PrimMSTWeightAM(const AMGraph *graph, int start) {
    int lowcost[MAX_VERTEX_NUM];
    bool in_tree[MAX_VERTEX_NUM] = {false};
    int i;
    int j;
    int min_cost;
    int next_vertex;
    int total_weight;

    if (graph == NULL || start < 0 || start >= graph->vexnum || graph->vexnum == 0) {
        return -1;
    }

    for (i = 0; i < graph->vexnum; i++) {
        lowcost[i] = graph->edges[start][i];
    }
    in_tree[start] = true;
    total_weight = 0;

    for (i = 1; i < graph->vexnum; i++) {
        min_cost = INF;
        next_vertex = -1;

        for (j = 0; j < graph->vexnum; j++) {
            if (!in_tree[j] && lowcost[j] < min_cost) {
                min_cost = lowcost[j];
                next_vertex = j;
            }
        }

        if (next_vertex == -1) {
            return -1;
        }

        in_tree[next_vertex] = true;
        total_weight += min_cost;

        for (j = 0; j < graph->vexnum; j++) {
            if (!in_tree[j] && graph->edges[next_vertex][j] < lowcost[j]) {
                lowcost[j] = graph->edges[next_vertex][j];
            }
        }
    }

    return total_weight;
}

/* Floyd 算法:允许每个顶点依次作为中转点,不断改进任意两点间的最短路。 */
void FloydAM(const AMGraph *graph, int dist[][MAX_VERTEX_NUM], int path[][MAX_VERTEX_NUM]) {
    int i;
    int j;
    int k;

    if (graph == NULL || dist == NULL || path == NULL) {
        return;
    }

    for (i = 0; i < graph->vexnum; i++) {
        for (j = 0; j < graph->vexnum; j++) {
            dist[i][j] = graph->edges[i][j];
            if (i != j && graph->edges[i][j] != INF) {
                path[i][j] = j;
            } else {
                path[i][j] = -1;
            }
        }
    }

    for (k = 0; k < graph->vexnum; k++) {
        for (i = 0; i < graph->vexnum; i++) {
            for (j = 0; j < graph->vexnum; j++) {
                if (dist[i][k] == INF || dist[k][j] == INF) {
                    continue;
                }

                if (dist[i][k] + dist[k][j] < dist[i][j]) {
                    dist[i][j] = dist[i][k] + dist[k][j];
                    path[i][j] = path[i][k];
                }
            }
        }
    }
}

/* 打印 Floyd 距离矩阵:便于一次性观察任意两点间的最短路径长度。 */
void PrintFloydDistances(const AMGraph *graph, int dist[][MAX_VERTEX_NUM]) {
    int i;
    int j;

    if (graph == NULL || dist == NULL) {
        return;
    }

    printf("Floyd distance matrix:\n   ");
    for (i = 0; i < graph->vexnum; i++) {
        printf("  %c", graph->vexs[i]);
    }
    printf("\n");

    for (i = 0; i < graph->vexnum; i++) {
        printf(" %c ", graph->vexs[i]);
        for (j = 0; j < graph->vexnum; j++) {
            if (dist[i][j] == INF) {
                printf("  -");
            } else {
                printf(" %2d", dist[i][j]);
            }
        }
        printf("\n");
    }
}

/* 打印 Floyd 还原出的具体路径:沿着 path 数组记录的“下一跳”一路走到终点。 */
void PrintFloydPathAM(const AMGraph *graph, int path[][MAX_VERTEX_NUM], int from, int to) {
    int current;

    if (graph == NULL || path == NULL || from < 0 || to < 0 ||
        from >= graph->vexnum || to >= graph->vexnum) {
        return;
    }

    if (from == to) {
        printf("%c\n", graph->vexs[from]);
        return;
    }

    if (path[from][to] == -1) {
        printf("No path\n");
        return;
    }

    current = from;
    printf("%c", graph->vexs[current]);
    while (current != to) {
        current = path[current][to];
        if (current == -1) {
            printf(" -> ?\n");
            return;
        }
        printf(" -> %c", graph->vexs[current]);
    }
    printf("\n");
}

/* Dijkstra 单源最短路径:dist 记录当前最短估计,finalized 记录顶点是否已确定最短路。 */
void DijkstraAM(const AMGraph *graph, int source, int dist[], int path[]) {
    bool finalized[MAX_VERTEX_NUM] = {false};
    int i;
    int j;
    int min_dist;
    int u;

    if (graph == NULL || dist == NULL || path == NULL || source < 0 || source >= graph->vexnum) {
        return;
    }

    for (i = 0; i < graph->vexnum; i++) {
        dist[i] = graph->edges[source][i];
        if (i != source && graph->edges[source][i] != INF) {
            path[i] = source;
        } else {
            path[i] = -1;
        }
    }

    dist[source] = 0;
    finalized[source] = true;

    for (i = 1; i < graph->vexnum; i++) {
        min_dist = INF;
        u = -1;

        for (j = 0; j < graph->vexnum; j++) {
            if (!finalized[j] && dist[j] < min_dist) {
                min_dist = dist[j];
                u = j;
            }
        }

        if (u == -1) {
            break;
        }

        finalized[u] = true;

        for (j = 0; j < graph->vexnum; j++) {
            if (!finalized[j] &&
                graph->edges[u][j] != INF &&
                dist[u] != INF &&
                dist[u] + graph->edges[u][j] < dist[j]) {
                dist[j] = dist[u] + graph->edges[u][j];
                path[j] = u;
            }
        }
    }
}

/* 打印 Dijkstra 结果:便于把每个顶点的最短路长度直接看出来。 */
void PrintDijkstraResult(const AMGraph *graph, int source, const int dist[]) {
    int i;

    if (graph == NULL || dist == NULL) {
        return;
    }

    printf("Dijkstra distances from %c: ", graph->vexs[source]);
    for (i = 0; i < graph->vexnum; i++) {
        if (dist[i] == INF) {
            printf("%c=INF ", graph->vexs[i]);
        } else {
            printf("%c=%d ", graph->vexs[i], dist[i]);
        }
    }
    printf("\n");
}

/* 生成拓扑序下标:关键路径既要正推最早时间,也要逆推最迟时间,所以先保留顺序。 */
bool GetTopologicalOrderAL(const ALGraph *graph, int order[], int *count) {
    int indegree[MAX_VERTEX_NUM] = {0};
    SqQueue queue;
    ArcNode *arc;
    int i;
    int v;
    int total;

    if (graph == NULL || order == NULL || count == NULL) {
        return false;
    }

    for (i = 0; i < graph->vexnum; i++) {
        arc = graph->vertices[i].firstarc;
        while (arc != NULL) {
            indegree[arc->adjvex]++;
            arc = arc->nextarc;
        }
    }

    InitQueue(&queue);
    for (i = 0; i < graph->vexnum; i++) {
        if (indegree[i] == 0) {
            Enqueue(&queue, i);
        }
    }

    total = 0;
    while (!IsQueueEmpty(&queue)) {
        Dequeue(&queue, &v);
        order[total++] = v;

        arc = graph->vertices[v].firstarc;
        while (arc != NULL) {
            indegree[arc->adjvex]--;
            if (indegree[arc->adjvex] == 0) {
                Enqueue(&queue, arc->adjvex);
            }
            arc = arc->nextarc;
        }
    }

    *count = total;
    return total == graph->vexnum;
}

/* 关键路径:先正推事件最早发生时间,再逆推最迟发生时间,最后找时差为 0 的活动。 */
bool CriticalPathAL(const ALGraph *graph,
                    int ve[],
                    int vl[],
                    bool critical[][MAX_VERTEX_NUM],
                    int *critical_length) {
    int order[MAX_VERTEX_NUM];
    int count;
    ArcNode *arc;
    int i;
    int v;
    int ee;
    int el;
    int project_length;

    if (graph == NULL || ve == NULL || vl == NULL || critical == NULL || critical_length == NULL) {
        return false;
    }

    if (!GetTopologicalOrderAL(graph, order, &count)) {
        return false;
    }

    for (i = 0; i < graph->vexnum; i++) {
        ve[i] = 0;
        for (v = 0; v < graph->vexnum; v++) {
            critical[i][v] = false;
        }
    }

    for (i = 0; i < count; i++) {
        v = order[i];
        arc = graph->vertices[v].firstarc;
        while (arc != NULL) {
            if (ve[v] + arc->weight > ve[arc->adjvex]) {
                ve[arc->adjvex] = ve[v] + arc->weight;
            }
            arc = arc->nextarc;
        }
    }

    project_length = 0;
    for (i = 0; i < graph->vexnum; i++) {
        if (ve[i] > project_length) {
            project_length = ve[i];
        }
        vl[i] = project_length;
    }

    for (i = count - 1; i >= 0; i--) {
        v = order[i];
        arc = graph->vertices[v].firstarc;
        while (arc != NULL) {
            if (vl[arc->adjvex] - arc->weight < vl[v]) {
                vl[v] = vl[arc->adjvex] - arc->weight;
            }
            arc = arc->nextarc;
        }
    }

    for (v = 0; v < graph->vexnum; v++) {
        arc = graph->vertices[v].firstarc;
        while (arc != NULL) {
            ee = ve[v];
            el = vl[arc->adjvex] - arc->weight;
            if (ee == el) {
                critical[v][arc->adjvex] = true;
            }
            arc = arc->nextarc;
        }
    }

    *critical_length = project_length;
    return true;
}

/* 打印关键路径结果:先输出 ve/vl,再列出关键活动,方便把表和图对应起来。 */
void PrintCriticalPathResult(const ALGraph *graph,
                             const int ve[],
                             const int vl[],
                             bool critical[][MAX_VERTEX_NUM],
                             int critical_length) {
    ArcNode *arc;
    int i;

    if (graph == NULL || ve == NULL || vl == NULL || critical == NULL) {
        return;
    }

    printf("Critical path project length: %d\n", critical_length);
    printf("ve: ");
    for (i = 0; i < graph->vexnum; i++) {
        printf("%c=%d ", graph->vertices[i].data, ve[i]);
    }
    printf("\n");

    printf("vl: ");
    for (i = 0; i < graph->vexnum; i++) {
        printf("%c=%d ", graph->vertices[i].data, vl[i]);
    }
    printf("\n");

    printf("Critical activities: ");
    for (i = 0; i < graph->vexnum; i++) {
        arc = graph->vertices[i].firstarc;
        while (arc != NULL) {
            if (critical[i][arc->adjvex]) {
                printf("<%c,%c> ", graph->vertices[i].data, graph->vertices[arc->adjvex].data);
            }
            arc = arc->nextarc;
        }
    }
    printf("\n");
}

/* 构造一张示例无向图:后面统一用它演示矩阵、邻接表、DFS、BFS。 */
void BuildSampleGraphs(AMGraph *matrix_graph, ALGraph *list_graph) {
    const char *vertices = "ABCDE";

    InitAMGraph(matrix_graph, vertices, false);
    InitALGraph(list_graph, vertices, false);

    AddEdgeAM(matrix_graph, 'A', 'B', 1);
    AddEdgeAM(matrix_graph, 'A', 'C', 1);
    AddEdgeAM(matrix_graph, 'B', 'D', 1);
    AddEdgeAM(matrix_graph, 'C', 'D', 1);
    AddEdgeAM(matrix_graph, 'C', 'E', 1);

    AddEdgeAL(list_graph, 'A', 'B', 1);
    AddEdgeAL(list_graph, 'A', 'C', 1);
    AddEdgeAL(list_graph, 'B', 'D', 1);
    AddEdgeAL(list_graph, 'C', 'D', 1);
    AddEdgeAL(list_graph, 'C', 'E', 1);
}

/* 构造示例 DAG:后面用它演示拓扑排序。 */
void BuildSampleDAG(ALGraph *dag) {
    const char *vertices = "ABCDEF";

    InitALGraph(dag, vertices, true);
    AddEdgeAL(dag, 'A', 'C', 1);
    AddEdgeAL(dag, 'A', 'D', 1);
    AddEdgeAL(dag, 'B', 'D', 1);
    AddEdgeAL(dag, 'C', 'E', 1);
    AddEdgeAL(dag, 'D', 'E', 1);
    AddEdgeAL(dag, 'E', 'F', 1);
}

/* 构造示例带权无向图:后面用它演示 Prim 最小生成树。 */
void BuildSampleWeightedUndirectedGraph(AMGraph *graph) {
    const char *vertices = "ABCDEF";

    InitAMGraph(graph, vertices, false);
    AddEdgeAM(graph, 'A', 'B', 6);
    AddEdgeAM(graph, 'A', 'C', 1);
    AddEdgeAM(graph, 'A', 'D', 5);
    AddEdgeAM(graph, 'B', 'C', 5);
    AddEdgeAM(graph, 'B', 'E', 3);
    AddEdgeAM(graph, 'C', 'D', 5);
    AddEdgeAM(graph, 'C', 'E', 6);
    AddEdgeAM(graph, 'C', 'F', 4);
    AddEdgeAM(graph, 'D', 'F', 2);
    AddEdgeAM(graph, 'E', 'F', 6);
}

/* 构造示例带权有向图:后面用它演示 Dijkstra 单源最短路径。 */
void BuildSampleWeightedDirectedGraph(AMGraph *graph) {
    const char *vertices = "ABCDE";

    InitAMGraph(graph, vertices, true);
    AddEdgeAM(graph, 'A', 'B', 10);
    AddEdgeAM(graph, 'A', 'C', 3);
    AddEdgeAM(graph, 'B', 'C', 1);
    AddEdgeAM(graph, 'B', 'D', 2);
    AddEdgeAM(graph, 'C', 'B', 4);
    AddEdgeAM(graph, 'C', 'D', 8);
    AddEdgeAM(graph, 'C', 'E', 2);
    AddEdgeAM(graph, 'D', 'E', 7);
    AddEdgeAM(graph, 'E', 'D', 9);
}

/* 构造示例 AOE 网:后面用它演示关键路径的 ve、vl 和关键活动。 */
void BuildSampleAOEGraph(ALGraph *graph) {
    const char *vertices = "ABCDEFG";

    InitALGraph(graph, vertices, true);
    AddEdgeAL(graph, 'A', 'B', 3);
    AddEdgeAL(graph, 'A', 'C', 2);
    AddEdgeAL(graph, 'B', 'D', 2);
    AddEdgeAL(graph, 'B', 'E', 3);
    AddEdgeAL(graph, 'C', 'D', 4);
    AddEdgeAL(graph, 'C', 'F', 3);
    AddEdgeAL(graph, 'D', 'G', 2);
    AddEdgeAL(graph, 'E', 'G', 3);
    AddEdgeAL(graph, 'F', 'G', 2);
}

int main(void) {
    AMGraph matrix_graph;
    AMGraph weighted_graph;
    AMGraph shortest_path_graph;
    ALGraph list_graph;
    ALGraph dag;
    ALGraph aoe_graph;
    char topo_order[MAX_VERTEX_NUM + 1];
    int dist[MAX_VERTEX_NUM];
    int floyd_dist[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
    int floyd_path[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
    int path[MAX_VERTEX_NUM];
    int ve[MAX_VERTEX_NUM];
    int vl[MAX_VERTEX_NUM];
    bool critical[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
    int critical_length;

    BuildSampleGraphs(&matrix_graph, &list_graph);

    PrintAMGraph(&matrix_graph);
    printf("\n");

    PrintALGraph(&list_graph);
    printf("\n");

    printf("DFS by adjacency matrix: ");
    DFSAM(&matrix_graph);
    printf("\n");

    printf("BFS by adjacency matrix: ");
    BFSAM(&matrix_graph);
    printf("\n");

    printf("DFS by adjacency list: ");
    DFSAL(&list_graph);
    printf("\n");

    printf("BFS by adjacency list: ");
    BFSAL(&list_graph);
    printf("\n");

    printf("Connected components in sample undirected graph: %d\n",
           CountConnectedComponentsAM(&matrix_graph));

    BuildSampleDAG(&dag);
    if (TopologicalSortAL(&dag, topo_order)) {
        printf("Topological order: %s\n", topo_order);
    } else {
        printf("Topological order: graph has a cycle\n");
    }

    BuildSampleWeightedUndirectedGraph(&weighted_graph);
    printf("Prim MST total weight: %d\n", PrimMSTWeightAM(&weighted_graph, 0));
    printf("Kruskal MST total weight: %d\n", KruskalMSTWeightAM(&weighted_graph));

    BuildSampleWeightedDirectedGraph(&shortest_path_graph);
    DijkstraAM(&shortest_path_graph, 0, dist, path);
    PrintDijkstraResult(&shortest_path_graph, 0, dist);
    FloydAM(&shortest_path_graph, floyd_dist, floyd_path);
    PrintFloydDistances(&shortest_path_graph, floyd_dist);
    printf("Floyd path A -> D: ");
    PrintFloydPathAM(&shortest_path_graph, floyd_path, 0, 3);
    printf("Floyd path A -> E: ");
    PrintFloydPathAM(&shortest_path_graph, floyd_path, 0, 4);

    BuildSampleAOEGraph(&aoe_graph);
    if (CriticalPathAL(&aoe_graph, ve, vl, critical, &critical_length)) {
        PrintCriticalPathResult(&aoe_graph, ve, vl, critical, critical_length);
    } else {
        printf("Critical path: graph has a cycle\n");
    }

    DestroyALGraph(&aoe_graph);
    DestroyALGraph(&dag);
    DestroyALGraph(&list_graph);
    return 0;
}

逐行注释版

/* 绗?{number}琛岋細寮曞叆褰撳墠婧愮爜鍚庨潰浼氱敤鍒扮殑澶存枃浠躲€?*/
#include <stdbool.h>
/* 绗?{number}琛岋細寮曞叆褰撳墠婧愮爜鍚庨潰浼氱敤鍒扮殑澶存枃浠躲€?*/
#include <stdio.h>
/* 绗?{number}琛岋細寮曞叆褰撳墠婧愮爜鍚庨潰浼氱敤鍒扮殑澶存枃浠躲€?*/
#include <stdlib.h>
/* 绗?{number}琛岋細寮曞叆褰撳墠婧愮爜鍚庨潰浼氱敤鍒扮殑澶存枃浠躲€?*/
#include <string.h>
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細瀹氫箟鍚庨潰瑕佸弽澶嶄娇鐢ㄧ殑瀹忓父閲忋€?*/
#define MAX_VERTEX_NUM 20
/* 绗?{number}琛岋細瀹氫箟鍚庨潰瑕佸弽澶嶄娇鐢ㄧ殑瀹忓父閲忋€?*/
#define INF 1000000000
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 邻接矩阵图结构:vexs 保存顶点名,edges 保存边权,vexnum/arcnum 记录规模。 */
/* 绗?{number}琛岋細寮€濮嬪畾涔変竴涓粨鏋勪綋绫诲瀷锛岀敤鏉ョ粍缁囩浉鍏虫暟鎹€?*/
typedef struct {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    char vexs[MAX_VERTEX_NUM];
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int edges[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int vexnum;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int arcnum;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    bool directed;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} AMGraph;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 邻接表边结点:adjvex 是邻接点下标,weight 是边权,nextarc 指向下一条边。 */
/* 绗?{number}琛岋細寮€濮嬪畾涔変竴涓粨鏋勪綋绫诲瀷锛岀敤鏉ョ粍缁囩浉鍏虫暟鎹€?*/
typedef struct ArcNode {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int adjvex;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int weight;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
    struct ArcNode *nextarc;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} ArcNode;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 邻接表顶点结点:data 保存顶点名,firstarc 指向第一条出边。 */
/* 绗?{number}琛岋細寮€濮嬪畾涔変竴涓粨鏋勪綋绫诲瀷锛岀敤鏉ョ粍缁囩浉鍏虫暟鎹€?*/
typedef struct {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    char data;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    ArcNode *firstarc;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} VNode;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 邻接表图结构:vertices 保存所有顶点,vexnum/arcnum 记录规模。 */
/* 绗?{number}琛岋細寮€濮嬪畾涔変竴涓粨鏋勪綋绫诲瀷锛岀敤鏉ョ粍缁囩浉鍏虫暟鎹€?*/
typedef struct {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
    VNode vertices[MAX_VERTEX_NUM];
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int vexnum;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int arcnum;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    bool directed;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} ALGraph;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 顺序队列:BFS 需要用它实现“先发现的顶点先扩展”。 */
/* 绗?{number}琛岋細寮€濮嬪畾涔変竴涓粨鏋勪綋绫诲瀷锛岀敤鏉ョ粍缁囩浉鍏虫暟鎹€?*/
typedef struct {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int data[MAX_VERTEX_NUM];
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int front;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int rear;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} SqQueue;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* Kruskal 用的边结构:把邻接矩阵中的有效边提出来,后面统一按权值排序。 */
/* 绗?{number}琛岋細寮€濮嬪畾涔変竴涓粨鏋勪綋绫诲瀷锛岀敤鏉ョ粍缁囩浉鍏虫暟鎹€?*/
typedef struct {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int u;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int v;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int weight;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
} Edge;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 初始化队列:front 和 rear 都回到 0,表示当前为空。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
void InitQueue(SqQueue *queue) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (queue == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    queue->front = 0;
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    queue->rear = 0;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 判断队列是否为空:front 和 rear 重合时表示没有元素。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
bool IsQueueEmpty(const SqQueue *queue) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
    return queue == NULL || queue->front == queue->rear;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 入队:把顶点下标压到队尾,供后续按 BFS 顺序处理。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
bool Enqueue(SqQueue *queue, int value) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int next_rear;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (queue == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    next_rear = (queue->rear + 1) % MAX_VERTEX_NUM;
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (next_rear == queue->front) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    queue->data[queue->rear] = value;
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    queue->rear = next_rear;
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
    return true;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 出队:取出当前队头顶点下标,并让 front 向后移动。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
bool Dequeue(SqQueue *queue, int *value) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (queue == NULL || value == NULL || IsQueueEmpty(queue)) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    *value = queue->data[queue->front];
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    queue->front = (queue->front + 1) % MAX_VERTEX_NUM;
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
    return true;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 初始化邻接矩阵:先清规模,再把矩阵设置成“无边”状态。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
void InitAMGraph(AMGraph *graph, const char *vertex_names, bool directed) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int i;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int j;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int length;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL || vertex_names == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    length = (int)strlen(vertex_names);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (length <= 0 || length > MAX_VERTEX_NUM) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    graph->vexnum = length;
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    graph->arcnum = 0;
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    graph->directed = directed;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        graph->vexs[i] = vertex_names[i];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
        for (j = 0; j < graph->vexnum; j++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
            if (i == j) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
                graph->edges[i][j] = 0;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
            } else {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
                graph->edges[i][j] = INF;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
            }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 按顶点名定位下标:后续加边和遍历都依赖这个映射。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
int LocateVertexAM(const AMGraph *graph, char vertex) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return -1;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
        if (graph->vexs[i] == vertex) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
            return i;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
    return -1;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 邻接矩阵加边:有向图只加一侧,无向图要对称补上另一侧。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
bool AddEdgeAM(AMGraph *graph, char from, char to, int weight) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int i;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int j;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL || weight <= 0) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    i = LocateVertexAM(graph, from);
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    j = LocateVertexAM(graph, to);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (i < 0 || j < 0 || i == j) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph->edges[i][j] == INF) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
        graph->arcnum++;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    graph->edges[i][j] = weight;
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (!graph->directed) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        graph->edges[j][i] = weight;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
    return true;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 打印邻接矩阵:便于把“图结构”和“矩阵内容”对应起来。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
void PrintAMGraph(const AMGraph *graph) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int i;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int j;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("Adjacency Matrix:\n   ");
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
        printf("  %c", graph->vexs[i]);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("\n");
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
        printf(" %c ", graph->vexs[i]);
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
        for (j = 0; j < graph->vexnum; j++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
            if (graph->edges[i][j] == INF) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
                printf("  -");
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
            } else {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
                printf(" %2d", graph->edges[i][j]);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
            }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
        printf("\n");
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 创建邻接表边结点:把邻接点和权值封装起来。 */
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
ArcNode *CreateArcNode(int adjvex, int weight) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    ArcNode *node;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    node = (ArcNode *)malloc(sizeof(ArcNode));
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (node == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    node->adjvex = adjvex;
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    node->weight = weight;
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    node->nextarc = NULL;
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
    return node;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 初始化邻接表:先写顶点,再把每个顶点的第一条边指针置空。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
void InitALGraph(ALGraph *graph, const char *vertex_names, bool directed) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int i;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int length;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL || vertex_names == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    length = (int)strlen(vertex_names);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (length <= 0 || length > MAX_VERTEX_NUM) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    graph->vexnum = length;
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    graph->arcnum = 0;
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    graph->directed = directed;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        graph->vertices[i].data = vertex_names[i];
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        graph->vertices[i].firstarc = NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 按顶点名定位邻接表下标:和邻接矩阵版本保持相同思路。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
int LocateVertexAL(const ALGraph *graph, char vertex) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return -1;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
        if (graph->vertices[i].data == vertex) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
            return i;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
    return -1;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 头插法挂一条边:新边结点插到邻接表最前面。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
bool AddArcNode(ALGraph *graph, int from, int to, int weight) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    ArcNode *node;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL || from < 0 || from >= graph->vexnum || to < 0 || to >= graph->vexnum) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    node = CreateArcNode(to, weight);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (node == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    node->nextarc = graph->vertices[from].firstarc;
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    graph->vertices[from].firstarc = node;
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
    return true;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 邻接表加边:无向图要补两次,有向图只补一次。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
bool AddEdgeAL(ALGraph *graph, char from, char to, int weight) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int i;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int j;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL || weight <= 0) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    i = LocateVertexAL(graph, from);
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    j = LocateVertexAL(graph, to);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (i < 0 || j < 0 || i == j) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (!AddArcNode(graph, i, j, weight)) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (!graph->directed) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
        if (!AddArcNode(graph, j, i, weight)) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
            return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
    graph->arcnum++;
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
    return true;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 打印邻接表:观察每个顶点后面都连了哪些邻接点。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
void PrintALGraph(const ALGraph *graph) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int i;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    ArcNode *arc;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("Adjacency List:\n");
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
        printf("%c -> ", graph->vertices[i].data);
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        arc = graph->vertices[i].firstarc;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
        while (arc != NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
            printf("(%c, w=%d) ", graph->vertices[arc->adjvex].data, arc->weight);
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
            arc = arc->nextarc;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
        printf("^\n");
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 释放邻接表:逐个顶点把边链表清掉,避免内存泄漏。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
void DestroyALGraph(ALGraph *graph) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int i;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    ArcNode *current;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    ArcNode *next;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        current = graph->vertices[i].firstarc;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
        while (current != NULL) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
            next = current->nextarc;
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
            free(current);
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
            current = next;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        graph->vertices[i].firstarc = NULL;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 访问顶点:统一输出接口,后续遍历都复用它。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
void VisitVertex(char vertex) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("%c ", vertex);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 邻接矩阵版 DFS 递归函数:先访问当前顶点,再递归访问尚未访问的邻接点。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
void DFSAMUtil(const AMGraph *graph, int v, bool visited[]) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int w;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    visited[v] = true;
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    VisitVertex(graph->vexs[v]);
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (w = 0; w < graph->vexnum; w++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
        if (!visited[w] && graph->edges[v][w] != INF && graph->edges[v][w] != 0) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
            DFSAMUtil(graph, w, visited);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 邻接矩阵版 DFS:兼顾非连通图,必要时从新的连通分量重新出发。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
void DFSAM(const AMGraph *graph) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    bool visited[MAX_VERTEX_NUM] = {false};
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
        if (!visited[i]) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
            DFSAMUtil(graph, i, visited);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 邻接矩阵版 BFS:先访问一个顶点,再按队列顺序逐层扩展。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
void BFSAM(const AMGraph *graph) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    bool visited[MAX_VERTEX_NUM] = {false};
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    SqQueue queue;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int i;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int v;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int w;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    InitQueue(&queue);
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
        if (visited[i]) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
            continue;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        visited[i] = true;
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
        VisitVertex(graph->vexs[i]);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
        Enqueue(&queue, i);
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
        while (!IsQueueEmpty(&queue)) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
            Dequeue(&queue, &v);
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
            for (w = 0; w < graph->vexnum; w++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
                if (!visited[w] && graph->edges[v][w] != INF && graph->edges[v][w] != 0) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
                    visited[w] = true;
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
                    VisitVertex(graph->vexs[w]);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
                    Enqueue(&queue, w);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
                }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
            }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 邻接表版 DFS 递归函数:顺着边链表把当前顶点能到的点一路走深。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
void DFSALUtil(const ALGraph *graph, int v, bool visited[]) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    ArcNode *arc;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    visited[v] = true;
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    VisitVertex(graph->vertices[v].data);
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    arc = graph->vertices[v].firstarc;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
    while (arc != NULL) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
        if (!visited[arc->adjvex]) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
            DFSALUtil(graph, arc->adjvex, visited);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        arc = arc->nextarc;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 邻接表版 DFS:写法和矩阵版类似,只是邻接点获取方式不同。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
void DFSAL(const ALGraph *graph) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    bool visited[MAX_VERTEX_NUM] = {false};
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
        if (!visited[i]) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
            DFSALUtil(graph, i, visited);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 邻接表版 BFS:队列逻辑不变,只是遍历邻接点时改成扫边链表。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
void BFSAL(const ALGraph *graph) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    bool visited[MAX_VERTEX_NUM] = {false};
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    SqQueue queue;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    ArcNode *arc;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int i;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int v;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    InitQueue(&queue);
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
        if (visited[i]) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
            continue;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        visited[i] = true;
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
        VisitVertex(graph->vertices[i].data);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
        Enqueue(&queue, i);
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
        while (!IsQueueEmpty(&queue)) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
            Dequeue(&queue, &v);
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
            arc = graph->vertices[v].firstarc;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
            while (arc != NULL) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
                if (!visited[arc->adjvex]) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
                    visited[arc->adjvex] = true;
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
                    VisitVertex(graph->vertices[arc->adjvex].data);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
                    Enqueue(&queue, arc->adjvex);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
                }
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
                arc = arc->nextarc;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
            }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 只做标记不输出的 DFS:后面统计连通分量时更方便复用。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
void DFSMarkAM(const AMGraph *graph, int v, bool visited[]) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int w;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    visited[v] = true;
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (w = 0; w < graph->vexnum; w++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
        if (!visited[w] && graph->edges[v][w] != INF && graph->edges[v][w] != 0) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
            DFSMarkAM(graph, w, visited);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 统计无向图连通分量:每发现一个还没访问过的顶点,就说明找到一个新分量。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
int CountConnectedComponentsAM(const AMGraph *graph) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    bool visited[MAX_VERTEX_NUM] = {false};
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int components;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return 0;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    components = 0;
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
        if (!visited[i]) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
            components++;
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
            DFSMarkAM(graph, i, visited);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
    return components;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 拓扑排序:不断取入度为 0 的顶点输出,并删除其发出的边。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
bool TopologicalSortAL(const ALGraph *graph, char order[]) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int indegree[MAX_VERTEX_NUM] = {0};
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    SqQueue queue;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    ArcNode *arc;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int i;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int v;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int count;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL || order == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        arc = graph->vertices[i].firstarc;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
        while (arc != NULL) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
            indegree[arc->adjvex]++;
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
            arc = arc->nextarc;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    InitQueue(&queue);
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
        if (indegree[i] == 0) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
            Enqueue(&queue, i);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    count = 0;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
    while (!IsQueueEmpty(&queue)) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
        Dequeue(&queue, &v);
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        order[count++] = graph->vertices[v].data;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        arc = graph->vertices[v].firstarc;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
        while (arc != NULL) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
            indegree[arc->adjvex]--;
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
            if (indegree[arc->adjvex] == 0) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
                Enqueue(&queue, arc->adjvex);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
            }
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
            arc = arc->nextarc;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    order[count] = '\0';
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
    return count == graph->vexnum;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 求并查集根结点:一路向上找代表元,并顺手做路径压缩。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
int FindSet(int parent[], int x) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (parent[x] != x) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        parent[x] = FindSet(parent, parent[x]);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
    return parent[x];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 合并两个集合:把秩较小的树挂到秩较大的树下面,减少后续查找高度。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
void UnionSet(int parent[], int rank[], int x, int y) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int root_x;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int root_y;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    root_x = FindSet(parent, x);
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    root_y = FindSet(parent, y);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (root_x == root_y) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (rank[root_x] < rank[root_y]) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        parent[root_x] = root_y;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
    } else if (rank[root_x] > rank[root_y]) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        parent[root_y] = root_x;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
    } else {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        parent[root_y] = root_x;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
        rank[root_x]++;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 给 qsort 用的比较函数:边权更小的边排在前面,方便 Kruskal 逐条尝试。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
int CompareEdgeByWeight(const void *lhs, const void *rhs) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
    const Edge *left;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
    const Edge *right;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    left = (const Edge *)lhs;
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    right = (const Edge *)rhs;
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
    return left->weight - right->weight;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* Kruskal 算法:把所有边按权值从小到大尝试,能接且不成环就选中。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
int KruskalMSTWeightAM(const AMGraph *graph) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    Edge edges[MAX_VERTEX_NUM * MAX_VERTEX_NUM];
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int parent[MAX_VERTEX_NUM];
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int rank[MAX_VERTEX_NUM] = {0};
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int edge_count;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int selected_edges;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int total_weight;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int i;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int j;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL || graph->directed || graph->vexnum == 0) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return -1;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    edge_count = 0;
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        parent[i] = i;
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
        for (j = i + 1; j < graph->vexnum; j++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
            if (graph->edges[i][j] != INF && graph->edges[i][j] != 0) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
                edges[edge_count].u = i;
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
                edges[edge_count].v = j;
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
                edges[edge_count].weight = graph->edges[i][j];
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
                edge_count++;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
            }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    qsort(edges, edge_count, sizeof(Edge), CompareEdgeByWeight);
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    total_weight = 0;
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    selected_edges = 0;
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < edge_count && selected_edges < graph->vexnum - 1; i++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
        if (FindSet(parent, edges[i].u) != FindSet(parent, edges[i].v)) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
            UnionSet(parent, rank, edges[i].u, edges[i].v);
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
            total_weight += edges[i].weight;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
            selected_edges++;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (selected_edges != graph->vexnum - 1) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return -1;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
    return total_weight;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* Prim 算法求最小生成树权值:每次把当前生成树到外部的最短边接进来。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
int PrimMSTWeightAM(const AMGraph *graph, int start) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int lowcost[MAX_VERTEX_NUM];
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    bool in_tree[MAX_VERTEX_NUM] = {false};
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int i;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int j;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int min_cost;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int next_vertex;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int total_weight;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL || start < 0 || start >= graph->vexnum || graph->vexnum == 0) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return -1;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        lowcost[i] = graph->edges[start][i];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    in_tree[start] = true;
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    total_weight = 0;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 1; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        min_cost = INF;
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        next_vertex = -1;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
        for (j = 0; j < graph->vexnum; j++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
            if (!in_tree[j] && lowcost[j] < min_cost) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
                min_cost = lowcost[j];
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
                next_vertex = j;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
            }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
        if (next_vertex == -1) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
            return -1;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        in_tree[next_vertex] = true;
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        total_weight += min_cost;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
        for (j = 0; j < graph->vexnum; j++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
            if (!in_tree[j] && graph->edges[next_vertex][j] < lowcost[j]) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
                lowcost[j] = graph->edges[next_vertex][j];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
            }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
    return total_weight;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* Floyd 算法:允许每个顶点依次作为中转点,不断改进任意两点间的最短路。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
void FloydAM(const AMGraph *graph, int dist[][MAX_VERTEX_NUM], int path[][MAX_VERTEX_NUM]) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int i;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int j;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int k;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL || dist == NULL || path == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
        for (j = 0; j < graph->vexnum; j++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
            dist[i][j] = graph->edges[i][j];
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
            if (i != j && graph->edges[i][j] != INF) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
                path[i][j] = j;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
            } else {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
                path[i][j] = -1;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
            }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (k = 0; k < graph->vexnum; k++) {
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
        for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
            for (j = 0; j < graph->vexnum; j++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
                if (dist[i][k] == INF || dist[k][j] == INF) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
                    continue;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
                }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
                if (dist[i][k] + dist[k][j] < dist[i][j]) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
                    dist[i][j] = dist[i][k] + dist[k][j];
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
                    path[i][j] = path[i][k];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
                }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
            }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 打印 Floyd 距离矩阵:便于一次性观察任意两点间的最短路径长度。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
void PrintFloydDistances(const AMGraph *graph, int dist[][MAX_VERTEX_NUM]) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int i;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int j;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL || dist == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("Floyd distance matrix:\n   ");
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
        printf("  %c", graph->vexs[i]);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("\n");
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
        printf(" %c ", graph->vexs[i]);
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
        for (j = 0; j < graph->vexnum; j++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
            if (dist[i][j] == INF) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
                printf("  -");
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
            } else {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
                printf(" %2d", dist[i][j]);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
            }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
        printf("\n");
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 打印 Floyd 还原出的具体路径:沿着 path 数组记录的“下一跳”一路走到终点。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
void PrintFloydPathAM(const AMGraph *graph, int path[][MAX_VERTEX_NUM], int from, int to) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int current;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL || path == NULL || from < 0 || to < 0 ||
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        from >= graph->vexnum || to >= graph->vexnum) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (from == to) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
        printf("%c\n", graph->vexs[from]);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (path[from][to] == -1) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
        printf("No path\n");
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    current = from;
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("%c", graph->vexs[current]);
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
    while (current != to) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        current = path[current][to];
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
        if (current == -1) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
            printf(" -> ?\n");
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
            return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
        printf(" -> %c", graph->vexs[current]);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("\n");
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* Dijkstra 单源最短路径:dist 记录当前最短估计,finalized 记录顶点是否已确定最短路。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
void DijkstraAM(const AMGraph *graph, int source, int dist[], int path[]) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    bool finalized[MAX_VERTEX_NUM] = {false};
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int i;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int j;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int min_dist;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int u;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL || dist == NULL || path == NULL || source < 0 || source >= graph->vexnum) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        dist[i] = graph->edges[source][i];
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
        if (i != source && graph->edges[source][i] != INF) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
            path[i] = source;
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
        } else {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
            path[i] = -1;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    dist[source] = 0;
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    finalized[source] = true;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 1; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        min_dist = INF;
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        u = -1;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
        for (j = 0; j < graph->vexnum; j++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
            if (!finalized[j] && dist[j] < min_dist) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
                min_dist = dist[j];
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
                u = j;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
            }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
        if (u == -1) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
            break;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        finalized[u] = true;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
        for (j = 0; j < graph->vexnum; j++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
            if (!finalized[j] &&
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
                graph->edges[u][j] != INF &&
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
                dist[u] != INF &&
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
                dist[u] + graph->edges[u][j] < dist[j]) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
                dist[j] = dist[u] + graph->edges[u][j];
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
                path[j] = u;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
            }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 打印 Dijkstra 结果:便于把每个顶点的最短路长度直接看出来。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
void PrintDijkstraResult(const AMGraph *graph, int source, const int dist[]) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL || dist == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("Dijkstra distances from %c: ", graph->vexs[source]);
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
        if (dist[i] == INF) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
            printf("%c=INF ", graph->vexs[i]);
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
        } else {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
            printf("%c=%d ", graph->vexs[i], dist[i]);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("\n");
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 生成拓扑序下标:关键路径既要正推最早时间,也要逆推最迟时间,所以先保留顺序。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
bool GetTopologicalOrderAL(const ALGraph *graph, int order[], int *count) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int indegree[MAX_VERTEX_NUM] = {0};
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    SqQueue queue;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    ArcNode *arc;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int i;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int v;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int total;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL || order == NULL || count == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        arc = graph->vertices[i].firstarc;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
        while (arc != NULL) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
            indegree[arc->adjvex]++;
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
            arc = arc->nextarc;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    InitQueue(&queue);
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
        if (indegree[i] == 0) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
            Enqueue(&queue, i);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    total = 0;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
    while (!IsQueueEmpty(&queue)) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
        Dequeue(&queue, &v);
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        order[total++] = v;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        arc = graph->vertices[v].firstarc;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
        while (arc != NULL) {
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
            indegree[arc->adjvex]--;
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
            if (indegree[arc->adjvex] == 0) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
                Enqueue(&queue, arc->adjvex);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
            }
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
            arc = arc->nextarc;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    *count = total;
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
    return total == graph->vexnum;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 关键路径:先正推事件最早发生时间,再逆推最迟发生时间,最后找时差为 0 的活动。 */
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
bool CriticalPathAL(const ALGraph *graph,
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
                    int ve[],
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
                    int vl[],
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
                    bool critical[][MAX_VERTEX_NUM],
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
                    int *critical_length) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int order[MAX_VERTEX_NUM];
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int count;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    ArcNode *arc;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int i;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int v;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int ee;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int el;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int project_length;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL || ve == NULL || vl == NULL || critical == NULL || critical_length == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (!GetTopologicalOrderAL(graph, order, &count)) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        ve[i] = 0;
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
        for (v = 0; v < graph->vexnum; v++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
            critical[i][v] = false;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < count; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        v = order[i];
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        arc = graph->vertices[v].firstarc;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
        while (arc != NULL) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
            if (ve[v] + arc->weight > ve[arc->adjvex]) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
                ve[arc->adjvex] = ve[v] + arc->weight;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
            }
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
            arc = arc->nextarc;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    project_length = 0;
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
        if (ve[i] > project_length) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
            project_length = ve[i];
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        vl[i] = project_length;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = count - 1; i >= 0; i--) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        v = order[i];
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        arc = graph->vertices[v].firstarc;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
        while (arc != NULL) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
            if (vl[arc->adjvex] - arc->weight < vl[v]) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
                vl[v] = vl[arc->adjvex] - arc->weight;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
            }
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
            arc = arc->nextarc;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (v = 0; v < graph->vexnum; v++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        arc = graph->vertices[v].firstarc;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
        while (arc != NULL) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
            ee = ve[v];
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
            el = vl[arc->adjvex] - arc->weight;
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
            if (ee == el) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
                critical[v][arc->adjvex] = true;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
            }
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
            arc = arc->nextarc;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
    *critical_length = project_length;
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
    return true;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 打印关键路径结果:先输出 ve/vl,再列出关键活动,方便把表和图对应起来。 */
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
void PrintCriticalPathResult(const ALGraph *graph,
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
                             const int ve[],
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
                             const int vl[],
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
                             bool critical[][MAX_VERTEX_NUM],
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
                             int critical_length) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    ArcNode *arc;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int i;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (graph == NULL || ve == NULL || vl == NULL || critical == NULL) {
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
        return;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("Critical path project length: %d\n", critical_length);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("ve: ");
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
        printf("%c=%d ", graph->vertices[i].data, ve[i]);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("\n");
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("vl: ");
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
        printf("%c=%d ", graph->vertices[i].data, vl[i]);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("\n");
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("Critical activities: ");
/* 绗?{number}琛岋細寮€濮嬩竴娆?for 寰幆锛屾寜鍥哄畾娆℃暟閲嶅鎵ц鍚庨潰鐨勮鍙ャ€?*/
    for (i = 0; i < graph->vexnum; i++) {
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
        arc = graph->vertices[i].firstarc;
/* 绗?{number}琛岋細寮€濮嬩竴娆?while 寰幆锛屽彧瑕佹潯浠舵垚绔嬪氨缁х画鎵ц銆?*/
        while (arc != NULL) {
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
            if (critical[i][arc->adjvex]) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
                printf("<%c,%c> ", graph->vertices[i].data, graph->vertices[arc->adjvex].data);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
            }
/* 绗?{number}琛岋細缁欏彉閲忋€佹暟缁勩€佸瓧娈垫垨鎸囬拡璧嬪€硷紝鏇存柊褰撳墠鐘舵€併€?*/
            arc = arc->nextarc;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
        }
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("\n");
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 构造一张示例无向图:后面统一用它演示矩阵、邻接表、DFS、BFS。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
void BuildSampleGraphs(AMGraph *matrix_graph, ALGraph *list_graph) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    const char *vertices = "ABCDE";
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    InitAMGraph(matrix_graph, vertices, false);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    InitALGraph(list_graph, vertices, false);
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAM(matrix_graph, 'A', 'B', 1);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAM(matrix_graph, 'A', 'C', 1);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAM(matrix_graph, 'B', 'D', 1);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAM(matrix_graph, 'C', 'D', 1);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAM(matrix_graph, 'C', 'E', 1);
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAL(list_graph, 'A', 'B', 1);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAL(list_graph, 'A', 'C', 1);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAL(list_graph, 'B', 'D', 1);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAL(list_graph, 'C', 'D', 1);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAL(list_graph, 'C', 'E', 1);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 构造示例 DAG:后面用它演示拓扑排序。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
void BuildSampleDAG(ALGraph *dag) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    const char *vertices = "ABCDEF";
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    InitALGraph(dag, vertices, true);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAL(dag, 'A', 'C', 1);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAL(dag, 'A', 'D', 1);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAL(dag, 'B', 'D', 1);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAL(dag, 'C', 'E', 1);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAL(dag, 'D', 'E', 1);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAL(dag, 'E', 'F', 1);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 构造示例带权无向图:后面用它演示 Prim 最小生成树。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
void BuildSampleWeightedUndirectedGraph(AMGraph *graph) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    const char *vertices = "ABCDEF";
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    InitAMGraph(graph, vertices, false);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAM(graph, 'A', 'B', 6);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAM(graph, 'A', 'C', 1);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAM(graph, 'A', 'D', 5);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAM(graph, 'B', 'C', 5);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAM(graph, 'B', 'E', 3);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAM(graph, 'C', 'D', 5);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAM(graph, 'C', 'E', 6);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAM(graph, 'C', 'F', 4);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAM(graph, 'D', 'F', 2);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAM(graph, 'E', 'F', 6);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 构造示例带权有向图:后面用它演示 Dijkstra 单源最短路径。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
void BuildSampleWeightedDirectedGraph(AMGraph *graph) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    const char *vertices = "ABCDE";
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    InitAMGraph(graph, vertices, true);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAM(graph, 'A', 'B', 10);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAM(graph, 'A', 'C', 3);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAM(graph, 'B', 'C', 1);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAM(graph, 'B', 'D', 2);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAM(graph, 'C', 'B', 4);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAM(graph, 'C', 'D', 8);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAM(graph, 'C', 'E', 2);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAM(graph, 'D', 'E', 7);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAM(graph, 'E', 'D', 9);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細杩欐槸鍘熸簮鐮侀噷宸茬粡瀛樺湪鐨勮鏄庢€ф敞閲娿€?*/
/* 构造示例 AOE 网:后面用它演示关键路径的 ve、vl 和关键活动。 */
/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
void BuildSampleAOEGraph(ALGraph *graph) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    const char *vertices = "ABCDEFG";
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    InitALGraph(graph, vertices, true);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAL(graph, 'A', 'B', 3);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAL(graph, 'A', 'C', 2);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAL(graph, 'B', 'D', 2);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAL(graph, 'B', 'E', 3);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAL(graph, 'C', 'D', 4);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAL(graph, 'C', 'F', 3);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAL(graph, 'D', 'G', 2);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAL(graph, 'E', 'G', 3);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    AddEdgeAL(graph, 'F', 'G', 2);
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細瀹氫箟鍑芥暟 ㈠紑濮嬪啓瀹冪殑鍏蜂綋瀹炵幇銆?*/
int main(void) {
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    AMGraph matrix_graph;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    AMGraph weighted_graph;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    AMGraph shortest_path_graph;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    ALGraph list_graph;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    ALGraph dag;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    ALGraph aoe_graph;
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    char topo_order[MAX_VERTEX_NUM + 1];
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int dist[MAX_VERTEX_NUM];
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int floyd_dist[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int floyd_path[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int path[MAX_VERTEX_NUM];
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int ve[MAX_VERTEX_NUM];
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int vl[MAX_VERTEX_NUM];
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    bool critical[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
/* 绗?{number}琛岋細澹版槑杩欎竴娈甸€昏緫浼氱敤鍒扮殑灞€閮ㄥ彉閲忋€佹寚閽堟垨缁撴瀯銆?*/
    int critical_length;
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    BuildSampleGraphs(&matrix_graph, &list_graph);
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    PrintAMGraph(&matrix_graph);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("\n");
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    PrintALGraph(&list_graph);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("\n");
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("DFS by adjacency matrix: ");
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    DFSAM(&matrix_graph);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("\n");
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("BFS by adjacency matrix: ");
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    BFSAM(&matrix_graph);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("\n");
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("DFS by adjacency list: ");
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    DFSAL(&list_graph);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("\n");
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("BFS by adjacency list: ");
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    BFSAL(&list_graph);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("\n");
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("Connected components in sample undirected graph: %d\n",
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
           CountConnectedComponentsAM(&matrix_graph));
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    BuildSampleDAG(&dag);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (TopologicalSortAL(&dag, topo_order)) {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
        printf("Topological order: %s\n", topo_order);
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
    } else {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
        printf("Topological order: graph has a cycle\n");
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    BuildSampleWeightedUndirectedGraph(&weighted_graph);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("Prim MST total weight: %d\n", PrimMSTWeightAM(&weighted_graph, 0));
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("Kruskal MST total weight: %d\n", KruskalMSTWeightAM(&weighted_graph));
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    BuildSampleWeightedDirectedGraph(&shortest_path_graph);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    DijkstraAM(&shortest_path_graph, 0, dist, path);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    PrintDijkstraResult(&shortest_path_graph, 0, dist);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    FloydAM(&shortest_path_graph, floyd_dist, floyd_path);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    PrintFloydDistances(&shortest_path_graph, floyd_dist);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("Floyd path A -> D: ");
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    PrintFloydPathAM(&shortest_path_graph, floyd_path, 0, 3);
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
    printf("Floyd path A -> E: ");
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    PrintFloydPathAM(&shortest_path_graph, floyd_path, 0, 4);
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    BuildSampleAOEGraph(&aoe_graph);
/* 绗?{number}琛岋細杩涜鏉′欢鍒ゆ柇锛屽喅瀹氬綋鍓嶆祦绋嬭蛋鍝釜鍒嗘敮銆?*/
    if (CriticalPathAL(&aoe_graph, ve, vl, critical, &critical_length)) {
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
        PrintCriticalPathResult(&aoe_graph, ve, vl, critical, critical_length);
/* 绗?{number}琛岋細鎵ц杩欎竴琛屼唬鐮侊紝缁х画鎺ㄨ繘褰撳墠閫昏緫銆?*/
    } else {
/* 绗?{number}琛岋細鎶婂綋鍓嶇粨鏋滄墦鍗板嚭鏉ワ紝鏂逛究瑙傚療绋嬪簭杩愯鎯呭喌銆?*/
        printf("Critical path: graph has a cycle\n");
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
    }
/* 绗?{number}琛岋細绌鸿锛岀敤鏉ュ垎闅斾笉鍚岀殑灏忔閫昏緫銆?*/

/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    DestroyALGraph(&aoe_graph);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    DestroyALGraph(&dag);
/* 绗?{number}琛岋細璋冪敤涓€涓嚱鏁帮紝鍊熷姪瀹冨畬鎴愬綋鍓嶈繖涓€姝ユ搷浣溿€?*/
    DestroyALGraph(&list_graph);
/* 绗?{number}琛岋細鎶婂綋鍓嶅嚱鏁扮殑缁撴灉杩斿洖缁欒皟鐢ㄨ€咃紝骞剁粨鏉熷綋鍓嶅嚱鏁般€?*/
    return 0;
/* 绗?{number}琛岋細浠g爜鍧楃粨鏉燂紝褰撳墠杩欎竴灞傞€昏緫鍦ㄨ繖閲屾敹鍙c€?*/
}

继续阅读