#include<iostream> #include<string.h> #include<queue> #include<vector> #include<algorithm> #include<map> using namespace std; const int INF = 999999; //首先是使用邻接矩阵存图 struct Graph { int vexnum; //顶点个数 int edge; //边的条数 int arc[128][128]; //存储图的边的权值 int min_dis[128][128]; //存储图最短路径 char information[128][128]; // 每个顶点对应的地点名字 }; //创建图 void createGraph(Graph & g) { printf("请输入地点的数量: "); scanf("%d", &g.vexnum); printf("请依次输入地点名称:\n"); for(int i = 1; i <= g.vexnum; i++) { scanf("%s", g.information[i]); } printf("请输入边的数量: "); scanf("%d", &g.edge); for (int i = 1; i <= g.vexnum; i++) { for (int k = 1; k <= g.vexnum; k++) { //初始化我们的邻接矩阵 if(i == k) g.arc[i][k] = 0; else g.arc[i][k] = INF; } } printf("请依次输入%d条边. \n", g.edge); for(int i = 1; i <= g.edge; i++) { printf("请输入第%d条边(按照起点 终点 边的权值格式进行输入): ", i); int from, end, value; scanf("%d%d%d", &from, &end, &value); g.arc[from][end] = value; g.arc[end][from] = value; } } // 使用floyd求解任意两点的最短路径 void floyd(Graph & g) { for (int i = 1; i <= g.vexnum; i++) { for (int k = 1; k <= g.vexnum; k++) { g.min_dis[i][k] = g.arc[i][k]; } } for (int k = 1; k <= g.vexnum; k++) { for (int i = 1; i <= g.vexnum; i++) { for (int j = 1; j <= g.vexnum; j++) { if(g.min_dis[i][k] + g.min_dis[k][j] < g.min_dis[i][j]) { g.min_dis[i][j] = g.min_dis[i][k] + g.min_dis[k][j]; } } } } } bool seen[20][150000]; // 求解从s为起点, 游览所有地点后的最短路径 int shortLength(int s, Graph g) { int n = g.vexnum; struct node { int u, mask, dist; }; queue<node> que; que.push({s, 1 << (s-1), 0}); seen[s][1 << (s-1)] = true; int ans = 0; while (!que.empty()) { node now = que.front(); int u = now.u; int mask = now.mask; int dist = now.dist; que.pop(); if (mask == (1 << n) - 1) { ans = dist; break; } // 搜索相邻的节点 for(int v = 1; v <= g.vexnum; v++) { if(g.arc[u][v] > 0 && g.arc[u][v] < INF) { int mask_v = mask | (1 << (v-1)); if(!seen[v][mask_v]) { que.push({v, mask_v, dist+g.arc[u][v]}); seen[v][mask_v] = true; } } } } return ans; } // 功能菜单 void menu() { printf("\n"); printf("1、求解两个地点的最短路径\n"); printf("2、安排最短路径游览所有的地点\n"); printf("3、退出\n"); printf("请输入你的选择:"); } int main() { Graph g; // 创建图 createGraph(g); // 求解图的最短路径 floyd(g); while(1) { menu(); int op; scanf("%d", &op); if(op == 1) { printf("请输入两个地点(以空格分割): "); char from[128], end[128]; scanf("%s %s", from, end); int i = -1, j = -1; for(int k = 1; k <= g.vexnum; k++) { if(strcmp(from, g.information[k]) == 0) { i = k; } if(strcmp(end, g.information[k]) == 0) { j = k; } } if(i == -1) { printf("%s不存在,请重试!\n", from); continue; } if(j == -1) { printf("%s不存在,请重试!\n", end); continue; } printf("%s 到 %s 的最短距离为 %d\n", from, end, g.min_dis[i][j]); } else if(op == 2) { printf("请输入游览的起始地点: "); char from[128]; scanf("%s", from); int i = -1; for(int k = 1; k <= g.vexnum; k++) { if(strcmp(from, g.information[k]) == 0) { i = k; } } if(i == -1) { printf("%s不存在,请重试!\n", from); continue; } int ans = shortLength(i, g); printf("以 %s 为起始地点,游览所有路径的最短路径为 %d\n", from, ans); } else { break; } } return 0; }
12-25
12-09
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交