狄克斯特拉算法求解村庄问题
2016-01-02 20:59
274 查看
问题:
给定n个村庄之间的交通图。若村庄i和j之间有路可通,则i和j用边连接,边上的权值Wij表示这条道路的长度。现打算在这n个村庄中选定一个村庄建一所医院。编写如下算法:
(1) 求出该医院应建在哪个村庄,才能使距离医院最远的村庄到医院的路程最短。
(2) 求出该医院应建在哪个村庄,能使其它所有村庄到医院的路径总和最短。
完成项目代码如下:
resource.h头文件
targetver.h头文件
stdafx.h头文件
stdafx.cpp文件
solveGraphQuestion.cpp文件
data.txt文件信息
运行结果:
给定n个村庄之间的交通图。若村庄i和j之间有路可通,则i和j用边连接,边上的权值Wij表示这条道路的长度。现打算在这n个村庄中选定一个村庄建一所医院。编写如下算法:
(1) 求出该医院应建在哪个村庄,才能使距离医院最远的村庄到医院的路程最短。
(2) 求出该医院应建在哪个村庄,能使其它所有村庄到医院的路径总和最短。
完成项目代码如下:
resource.h头文件
//{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by Resource.rc // 新对象的下一组默认值 // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 101 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif
targetver.h头文件
#pragma once // 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。 // 如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h,并将 // WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。 #include <SDKDDKVer.h>
stdafx.h头文件
// stdafx.h : 标准系统包含文件的包含文件, // 或是经常使用但不常更改的 // 特定于项目的包含文件 // #pragma once #include "targetver.h" #include <stdio.h> #include <tchar.h> // TODO: 在此处引用程序需要的其他头文件 #include<iostream> #include<fstream> #include<sstream> #include<string> using namespace std; const int MAX_N = 100;//定义最大存储空间 const int INF = 65535;//定义为无穷大 //数据节点 //顶点信息 class Vertex { public: int vername;//顶点名 int number;//顶点下标 }; //图信息 class MatrixGraph { public: int edges[MAX_N][MAX_N];//边 int Tvertex, Tedges;//总顶点,总边数 Vertex vert[MAX_N];//顶点信息 int weight[MAX_N];//边权重 }; class Graph { public: //构造 Graph(); //析构 ~Graph(); //读取文件->图信息 void getInfo(string ); //创建图 void CreateGraphMatrix(); //求任意二者间最短距离 void solveMin(); //求解问题 void solveQuestion(); private: MatrixGraph graph; string vertex;//顶点 string weight;//权重 string edges[MAX_N];//边 int Tedges;//边数 stringstream sstr;//string类型转换变量 int disMin[MAX_N][MAX_N];//最短距离 //获取下标 int location(MatrixGraph , int ); //初始化邻接矩阵 void InitMatrix(); //初始化距离数组和路径数组 void InitDist(); };
stdafx.cpp文件
// stdafx.cpp : 只包括标准包含文件的源文件 // solveGraphQuestion.pch 将作为预编译头 // stdafx.obj 将包含预编译类型信息 #include "stdafx.h" // TODO: 在 STDAFX.H 中 // 引用任何所需的附加头文件,而不是在此文件中引用 //构造 Graph::Graph() { Graph::InitMatrix();//初始化矩阵 Graph::InitDist();//初始化距离 } //析构 Graph::~Graph(){} //搜索下标 int Graph::location(MatrixGraph g, int index) { for (int i = 0; i < g.Tvertex; i++) { if (index == g.vert[i].number) { return i; } } return -1; } //邻接矩阵初始化 void Graph::InitMatrix() { { for (int i = 0; i < MAX_N; i++) { for (int j = 0; j < MAX_N; j++) { graph.edges[i][j] = INF;//初始化为无穷大 } } } } //村庄间距离初始化 void Graph::InitDist() { for (int i = 0; i < MAX_N; i++) { for (int j = 0; j < MAX_N; j++) { disMin[i][j] = INF;//初始化为无穷大 } } } //读取文件->图信息 void Graph::getInfo(string filename) { ifstream readfile; readfile.open(filename, ios::in); getline(readfile, vertex);//读取顶点 getline(readfile, weight);//读取权重 //读取边 int i = 0; while (!readfile.eof()) { if (getline(readfile, edges[i]).good())//边值正常 { i++; } } readfile.close(); Tedges = i;//总边数 } //创建图 void Graph::CreateGraphMatrix() { int edge1, edge2; graph.Tvertex = vertex.length();//顶点数 graph.Tedges = Tedges;//边数 //处理顶点 for (int i = 0; i < graph.Tvertex; i++) { //转换 sstr.clear();//清空内存 sstr << vertex[i];//写入一个顶点 sstr >> graph.vert[i].vername;//获取一个顶点 graph.vert[i].number = i;//定义顶点编号 } //处理边 for (int i = 0; i < graph.Tedges; i++) { //转换 sstr.clear();//清空内存 sstr << weight[i];//写入权重 sstr >> graph.weight[i];//获取权重 sstr.clear(); sstr << edges[i][0];//获取一条边始点 sstr >> edge1; sstr.clear(); sstr << edges[i][1];//获取一条边终点 sstr >> edge2; int p1 = location(graph, edge1);//获取始点边下标 int p2 = location(graph, edge2);//获取终点边下标 graph.edges[p1][p2] = graph.edges[p2][p1] = graph.weight[i];//写入该边权重->无向 } } //求任意村庄间最短距离 void Graph::solveMin() { //默认最短距离 for (int i = 0; i < graph.Tvertex; i++) { for (int j = 0; j < graph.Tvertex; j++) { disMin[i][j] = graph.edges[i][j]; } } //求最短距离 for (int k = 0; k < graph.Tvertex; k++) { for (int i = 0; i < graph.Tvertex; i++) { for (int j = 0; j < graph.Tvertex; j++) { if (disMin[i][j]>disMin[i][k] + disMin[k][j]) { disMin[i][j] = disMin[i][k] + disMin[k][j];//修改最短距离 } } } } } //求解问题 void Graph::solveQuestion() { int min[MAX_N];//某村庄到其他村庄的最短距离中的最大距离 int totalMin[MAX_N] = { 0 };//某村庄到其他村庄的最短距离之和 //遍历求村庄到其他村庄的最短距离中的最大距离 //以及到其他村庄的最短距离之和 for (int i = 0; i < graph.Tvertex; i++) { min[i] = disMin[i][0];//默认距离最大 for (int j = 0; j<graph.Tvertex; j++) { //若存在更大值,则更新 if (min[i] < disMin[i][j]) { min[i] = disMin[i][j];//修改最大值 } totalMin[i] += disMin[i][j];//距离之和 } } //求解问题 int ques_1 = min[0], loc_1 = 0;//问题一最小值以及村庄下标 int ques_2 = totalMin[0], loc_2 = 0;//问题二最小值以及村庄下标 for (int i = 0; i < graph.Tvertex; i++) { //存在更小距离 if (ques_1>min[i]) { ques_1 = min[i];//修改距离 loc_1 = i;//修改村庄下标 } //存在更小距离之和 if (ques_2 > totalMin[i]) { ques_2 = totalMin[i];//修改距离 loc_2 = i;//修改下标 } } //输出结果 cout << "question 1->村庄标号 " << loc_1 << ", 最短距离 " << ques_1 << endl; cout << "question 2->村庄标号 " << loc_2 << ", 最短距离 " << ques_2 << endl; }
solveGraphQuestion.cpp文件
// solveGraphQuestion.cpp : 定义控制台应用程序的入口点。 // //代码所解决问题说明见readMe.txt #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { Graph g; g.getInfo("data.txt");//读图 g.CreateGraphMatrix();//创建临接矩阵 g.solveMin();//求所有最短路径 g.solveQuestion();//求解问题 return 0; }
data.txt文件信息
012345 5873459561 01 02 03 05 12 23 25 34 35 45
运行结果:
相关文章推荐
- 适配器模式
- C++—STL学习笔记
- 文章标题
- 随笔
- leetcode之Spiral Matrix II
- 火焰艺术字效果制作
- Spring Boot学习笔记-外部化属性配置
- 读OpenCV之小侃高斯滤波
- [PTA] week12 4-10 Strongly Connected Components
- 一道闭包题题解
- 图像处理与计算机视觉:基础,经典以及最近发展(5)计算机视觉
- CABasicAnimation animationWithKeyPath Types
- 初识JavaScript,Ajax,jQuery,并比较三者关系
- 应用层open(read、write、close)怎样调用驱动open(read、write、close)函数的?
- 黑马程序员——java基础之多态
- JAVA反射与代理
- Container With Most Water
- C语言+鞍点
- iOS 设备尺寸以及图标尺寸
- 简单配置bind9 的master 和slave