【数据结构与算法实验】建立图并输出最短路径矩阵与最短距离矩阵

实验目的:

在代码实践中,回顾图的表示与最短路径算法知识,提高写代码速度。

预期效果:

第一行输入两个整数m、n(以空格间隔),分别为图的顶点数与边数。然后输入n行,用于输入边,格式为:顶点1 顶点2 权重。输出图的邻接矩阵,然后用求多源最短路径,输出最短路径矩阵与距离矩阵。

实验思路:

前提:所有边权重均为正整数,不存在的边定义为9999,最大顶点数为12。

用邻接矩阵法表示图,用Floyd算法求解多源最短路径。

实验代码:

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

/* 图实现 */
#define maxVertaxNumber 12
#define NOEDGE 9999

typedef int weightType;
typedef char orderType;
typedef int vertax;

struct GNode {
    int NVertax;
    int NEdge;
    weightType G[maxVertaxNumber][maxVertaxNumber];
    orderType order[maxVertaxNumber];
};
typedef struct GNode *Graph;

struct ENode {
    vertax v1,v2;
    weightType weight;
};
typedef struct ENode *Edge;

Graph createMGraph(int NVertax) {
    Graph ret = (Graph)malloc(sizeof(struct GNode));
    ret->NVertax = NVertax;
    ret->NEdge = 0;
    for (int i=0;i<NVertax;i++) {
        ret->order[i] = i;
        for (int j=0;j<NVertax;j++) {
            ret->G[i][j] = NOEDGE;
        }
    }

    return ret;
}

void insertEgde(Graph graph, Edge edge) {
    graph->G[edge->v1][edge->v2] = edge->weight;
    graph->NEdge++;
}

/* 建图 
    输入格式为:
        Nv Ne
        v1 v2 weight
        v1 v2 weight
        ……
*/
Graph BuildGraph() {
    int Nv,Ne;
    scanf("%d %d",&Nv,&Ne);
    Graph graph = createMGraph(Nv);
    if(Ne!=0) {
        Edge tempEdge = (Edge)malloc(sizeof(tempEdge));
        for (int i=0;i<Ne;i++) {
            scanf("%d %d %d",&(tempEdge->v1),&(tempEdge->v2),&(tempEdge->weight));
            insertEgde(graph,tempEdge);
        }
    }
    return graph;
}
/* 图实现 完 */

/* 主程序 */

// 最短路径数据存储结构
struct dataNode {
    int NVertax;
    weightType D[maxVertaxNumber][maxVertaxNumber];
    vertax path[maxVertaxNumber][maxVertaxNumber];
};
typedef struct dataNode *ptrToData;

// 输出邻接矩阵 函数实现
void showMatrixGraph(Graph graph) {
    puts("图的邻接矩阵如下:");
    for (int i=0; i<graph->NVertax; i++) {
        printf("\t%d",graph->order[i]);
    }
    printf("\n");
    for (int i=0; i<graph->NVertax; i++) {
        printf("%d",i);
        for (int j=0; j<graph->NVertax; j++) {
            printf("\t%d",graph->G[i][j]);
        }
        printf("\n");
    }
}

// Floyd算法实现
ptrToData doFloyd (Graph graph) {
    ptrToData data = (ptrToData)malloc(sizeof(struct dataNode));
    int n = graph->NVertax;
    data->NVertax = n; 
    for (int i=0; i<n; i++) {
        for (int j=0; j<n; j++) {
            data->D[i][j] = graph->G[i][j];
            data->path[i][j] = -1;
        }
    }
    for (int k=0; k<n; k++) {
        for (int i=0; i<n; i++) {
            for (int j=0; j<n; j++) {
                if(data->D[i][k]+data->D[k][j]<data->D[i][j]) {
                    data->D[i][j] = data->D[i][k]+data->D[k][j];
                    data->path[i][j] = k;
                }
            }
        }
    }
    return data;
}

// 输出数据矩阵 函数实现
void showDataMatrix(ptrToData data) {
    int n = data->NVertax;
    puts("最短路径矩阵如下:");
    for (int i=0; i<n; i++) {
        printf("\t%d",i);
    }
    printf("\n");
    for (int i=0; i<n; i++) {
        printf("%d",i);
        for (int j=0; j<n; j++) {
            printf("\t%d",data->path[i][j]);
        }
        printf("\n");
    }
    printf("\n");
    puts("最短距离矩阵如下:");
    for (int i=0; i<n; i++) {
        printf("\t%d",i);
    }
    printf("\n");
    for (int i=0; i<n; i++) {
        printf("%d",i);
        for (int j=0; j<n; j++) {
            printf("\t%d",data->D[i][j]);
        }
        printf("\n");
    }
}

int main() {
    // 建图
    Graph graph = BuildGraph();
    // 输出邻接矩阵
    showMatrixGraph(graph);
    // 进行Floyd算法并存储数据
    ptrToData data = doFloyd(graph);
    // 输出数据
    showDataMatrix(data);
    
    getchar();
    getchar();
    return 0;
}

测试结果:

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为了更好地回答你的问题,可以先确定一下使用哪个算法来求解最短路径,比如 Dijkstra 算法或 Floyd 算法。接下来,我们可以使用 Python 来实现: 假设我们要求解的是有向,那么我们可以使用邻接矩阵来表示。具体来说,我们可以使用一个二维列表来表示这个矩阵,其中列表的第 i 行第 j 列表示从顶点 i 到顶点 j 的边的权值。如果不存在从顶点 i 到顶点 j 的边,则权值为一个很大的数(比如 999999)。假设有 n 个顶点,则邻接矩阵的大小为 n × n。 下面是使用 Dijkstra 算法来求解最短路径的 Python 代码,其中我们假定已经给出了邻接矩阵 graph 和起点 start: ```python import heapq def dijkstra(graph, start): n = len(graph) visited = [False] * n dist = [float('inf')] * n dist[start] = 0 heap = [(0, start)] while heap: (d, u) = heapq.heappop(heap) if visited[u]: continue visited[u] = True for v in range(n): if graph[u][v] != 999999 and not visited[v]: alt = dist[u] + graph[u][v] if alt < dist[v]: dist[v] = alt heapq.heappush(heap, (dist[v], v)) return dist ``` 上述代码中,我们使用了堆来优化 Dijkstra 算法的时间复杂度。具体来说,我们维护了一个最小堆 heap,其中每个元素都是一个二元组 (d, u),表示从起点到顶点 u 的距离为 d。在每次循环中,我们取出堆顶元素 (d, u),然后对于所有与 u 相邻的顶点 v,如果从起点到 v 的距离可以通过从起点到 u 再加上从 u 到 v 来更新,则更新距离,并将 (dist[v], v) 加入堆中。 最后,我们可以调用 dijkstra 函数来求解最短路径,并输出结果: ```python graph = [ [0, 10, 999999, 999999], [999999, 0, 5, 999999], [999999, 2, 0, 1], [999999, 999999, 999999, 0] ] start = 0 dist = dijkstra(graph, start) for i, d in enumerate(dist): print(f"The shortest distance from {start} to {i} is {d}") ``` 上述代码中,我们使用了一个邻接矩阵来表示有向,其中 0 表示同一个顶点,999999 表示没有边相连。我们将起点设为 0,然后调用 dijkstra 函数求解最短路径。最后,我们遍历所有顶点,输出从起点到该顶点的最短路径长度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值