#include <Windows.h>
#include <string>
#include <vector>
#include <unordered_map>
#include <queue>
#include <climits>
#include <sstream>
#include "Resource.h"
// 登录对话框的消息处理函数
INT_PTR CALLBACK LoginDlgProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp) {
switch (msg) {
case WM_COMMAND:
if (wp == IDOK || wp == IDCANCEL) {
EndDialog(hDlg, wp);
return TRUE;
}
break;
case WM_CLOSE:
EndDialog(hDlg, IDCANCEL);
return TRUE;
}
return FALSE;
}
// 主界面对话框的消息处理函数(修改)
INT_PTR CALLBACK MainDlgProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp) {
switch (msg) {
case WM_COMMAND:
if (wp == IDOK || wp == IDCANCEL) {
EndDialog(hDlg, wp);
return TRUE;
}
break;
case WM_CLOSE:
EndDialog(hDlg, IDCANCEL);
return TRUE;
}
return FALSE;
}
// 定义校园地点(顶点)
enum CampusPlace {
PLACE_BEI_DAMEN, // 北大门
PLACE_XI_DAMEN, // 西大门
PLACE_NAN_DAMEN, // 南大门
PLACE_SONGSHAN_HU, // 松山湖
PLACE_XIN_TIYU_CHANG, // 新体育场
PLACE_OLD_TIYU_CHANG, // 老体育场
PLACE_LEQUN_LOU, // 乐群楼
PLACE_QIUZHEN_LOU, // 求真楼
PLACE_JINGYE_LOU, // 敬业楼
PLACE_HOU_CUN_G1, // 乐业楼
PLACE_HAI_TANG_YUAN, // 海棠苑
PLACE_WU_TONG_YUAN, // 梧桐苑
PLACE_XUE_SHU_JIAO_LIU_ZHONG_XIN ,// 学术交流中心
PLACE_SHUANG_CHUANG_LOU, //双创大楼
PLACE_GONG_YE_ZHONG_XIN, //工业中心
PLACE_XING_ZHEN_LOU, //行政楼
PLACE_JUN_ZHU_YUAN, //筠竹苑
PLACE_XIANG_ZHANG_YUN, //香樟苑
PLACE_SAN_SI_SHI_TANG, //第二食堂
PLACE_YI_ER_SHI_TANG, //第一食堂
};
// 地点名称映射
const std::unordered_map<CampusPlace, std::wstring> PlaceNames = {
{PLACE_BEI_DAMEN, L"北大门"},
{PLACE_XI_DAMEN, L"西大门"},
{PLACE_NAN_DAMEN, L"南大门"},
{PLACE_SONGSHAN_HU, L"松山湖"},
{PLACE_XIN_TIYU_CHANG, L"新体育场"},
{PLACE_OLD_TIYU_CHANG, L"老体育场"},
{PLACE_LEQUN_LOU, L"乐群楼"},
{PLACE_QIUZHEN_LOU, L"求真楼"},
{PLACE_JINGYE_LOU, L"敬业楼"},
{PLACE_HOU_CUN_G1, L"乐业楼"},
{PLACE_HAI_TANG_YUAN, L"海棠苑"},
{PLACE_WU_TONG_YUAN, L"梧桐苑"},
{PLACE_XUE_SHU_JIAO_LIU_ZHONG_XIN, L"学术交流中心"},
{PLACE_SHUANG_CHUANG_LOU, L"双创大楼"},
{PLACE_GONG_YE_ZHONG_XIN,L"工业中心"},
{PLACE_XING_ZHEN_LOU,L"行政楼"},
{PLACE_JUN_ZHU_YUAN,L"筠竹苑"},
{PLACE_XIANG_ZHANG_YUN,L"香樟苑"},
{PLACE_SAN_SI_SHI_TANG,L"第二食堂"},
{PLACE_YI_ER_SHI_TANG,L"第一食堂"}
};
// 优化后的校园地图邻接表
std::unordered_map<CampusPlace, std::vector<std::pair<CampusPlace, int>>> CampusGraph = {
// 北大门
{PLACE_BEI_DAMEN, {
{PLACE_HOU_CUN_G1, 8}, // 北大门 → 乐业楼 (8分钟)
{PLACE_XIN_TIYU_CHANG, 8}, // 北大门 → 新体育场 (8分钟)
{PLACE_QIUZHEN_LOU, 15}, // 北大门 → 求真楼 (15分钟,直达)
{ PLACE_SHUANG_CHUANG_LOU, 3},
{PLACE_GONG_YE_ZHONG_XIN,2},
{PLACE_SAN_SI_SHI_TANG,10},
}},
// 西大门
{PLACE_XI_DAMEN, {
{PLACE_WU_TONG_YUAN, 3}, // 西大门 → 梧桐苑 (3分钟)
{PLACE_HAI_TANG_YUAN, 5}, // 西大门 → 海棠苑 (5分钟)
{PLACE_LEQUN_LOU, 10} // 西大门 → 乐群楼 (10分钟)
}},
// 南大门
{PLACE_NAN_DAMEN, {
{PLACE_XUE_SHU_JIAO_LIU_ZHONG_XIN, 3}, // 南大门 → 学术交流中心 (3分钟)
{PLACE_JINGYE_LOU, 12}, // 南大门 → 敬业楼 (12分钟)
{PLACE_SONGSHAN_HU, 15} // 南大门 → 松山湖 (15分钟)
}},
// 松山湖
{PLACE_SONGSHAN_HU, {
{PLACE_XIN_TIYU_CHANG, 3}, // 松山湖 → 新体育场 (3分钟)
{PLACE_OLD_TIYU_CHANG, 4}, // 松山湖 → 老体育场 (4分钟)
{PLACE_HAI_TANG_YUAN, 6}, // 松山湖 → 海棠苑 (6分钟)
{PLACE_NAN_DAMEN, 15} // 松山湖 → 南大门 (15分钟)
}},
// 新体育场
{PLACE_XIN_TIYU_CHANG, {
{PLACE_BEI_DAMEN, 8}, // 新体育场 → 北大门 (8分钟)
{PLACE_SONGSHAN_HU, 3}, // 新体育场 → 松山湖 (3分钟)
{PLACE_OLD_TIYU_CHANG, 5} // 新体育场 → 老体育场 (5分钟)
}},
// 老体育场
{PLACE_OLD_TIYU_CHANG, {
{PLACE_SONGSHAN_HU, 4}, // 老体育场 → 松山湖 (4分钟)
{PLACE_XIN_TIYU_CHANG, 5}, // 老体育场 → 新体育场 (5分钟)
{PLACE_LEQUN_LOU, 2} // 老体育场 → 乐群楼 (2分钟)
}},
// 乐群楼
{PLACE_LEQUN_LOU, {
{PLACE_OLD_TIYU_CHANG, 2}, // 乐群楼 → 老体育场 (2分钟)
{PLACE_QIUZHEN_LOU, 3}, // 乐群楼 → 求真楼 (3分钟)
{PLACE_JINGYE_LOU, 4}, // 乐群楼 → 敬业楼 (4分钟)
{PLACE_XI_DAMEN, 10} // 乐群楼 → 西大门 (10分钟)
}},
// 求真楼
{PLACE_QIUZHEN_LOU, {
{PLACE_LEQUN_LOU, 3}, // 求真楼 → 乐群楼 (3分钟)
{PLACE_BEI_DAMEN, 15}, // 求真楼 → 北大门 (15分钟)
{PLACE_JINGYE_LOU, 2} // 求真楼 → 敬业楼 (2分钟)
}},
// 敬业楼
{PLACE_JINGYE_LOU, {
{PLACE_LEQUN_LOU, 4}, // 敬业楼 → 乐群楼 (4分钟)
{PLACE_QIUZHEN_LOU, 2}, // 敬业楼 → 求真楼 (2分钟)
{PLACE_NAN_DAMEN, 12} // 敬业楼 → 南大门 (12分钟)
}},
// 乐业楼
{PLACE_HOU_CUN_G1, {
{PLACE_BEI_DAMEN, 5}, // 航训楼G1 → 北大门 (5分钟)
{PLACE_XIN_TIYU_CHANG, 10}, // 航训楼G1 → 新体育场 (10分钟)
{PLACE_LEQUN_LOU, 4}
}},
// 海棠苑
{PLACE_HAI_TANG_YUAN, {
{PLACE_SONGSHAN_HU, 6}, // 海棠苑 → 松山湖 (6分钟)
{PLACE_WU_TONG_YUAN, 2}, // 海棠苑 → 梧桐苑 (2分钟)
{PLACE_XI_DAMEN, 5} // 海棠苑 → 西大门 (5分钟)
}},
// 梧桐苑
{PLACE_WU_TONG_YUAN, {
{PLACE_HAI_TANG_YUAN, 2}, // 梧桐苑 → 海棠苑 (2分钟)
{PLACE_XI_DAMEN, 3} // 梧桐苑 → 西大门 (3分钟)
}},
// 学术交流中心
{PLACE_XUE_SHU_JIAO_LIU_ZHONG_XIN, {
{PLACE_NAN_DAMEN, 3}, // 学术交流中心 → 南大门 (3分钟)
{PLACE_JINGYE_LOU, 10} // 学术交流中心 → 敬业楼 (10分钟)
}}
};
// Dijkstra算法:计算起点到终点的最短路径
std::pair<std::vector<CampusPlace>, int> DijkstraShortestPath(CampusPlace start, CampusPlace end) {
// 距离数组:记录每个地点的最短距离
std::unordered_map<CampusPlace, int> dist;
// 前驱节点数组:记录路径
std::unordered_map<CampusPlace, CampusPlace> prev;
// 优先队列(小顶堆):存储 (当前距离, 地点)
std::priority_queue<std::pair<int, CampusPlace>,
std::vector<std::pair<int, CampusPlace>>,
std::greater<std::pair<int, CampusPlace>>> pq;
// 1. 初始化所有距离为无穷大
for (const auto& entry : CampusGraph) {
dist[entry.first] = INT_MAX;
prev[entry.first] = (CampusPlace)-1;
}
// 起点到自身的距离为0
dist[start] = 0;
pq.push({0, start});
while (!pq.empty()) {
// 2. 取出当前距离最小的节点
auto current = pq.top().second;
pq.pop();
// 如果已经到达终点,可以提前退出以提高效率
if (current == end) {
break;
}
// 3. 遍历当前节点的所有邻居
for (const auto& neighbor_pair : CampusGraph[current]) {
CampusPlace next_place = neighbor_pair.first;
int weight = neighbor_pair.second;
// 4. 松弛操作:更新距离
if (dist[current] != INT_MAX && dist[next_place] > dist[current] + weight) {
dist[next_place] = dist[current] + weight;
prev[next_place] = current; // 更新前驱节点
pq.push({dist[next_place], next_place});
}
}
}
// 5. 从终点回溯到起点,重建路径
std::vector<CampusPlace> path;
if (dist[end] != INT_MAX) { // 只有当终点可达时才重建路径
for (CampusPlace p = end; p != (CampusPlace)-1; p = prev[p]) {
path.push_back(p);
}
std::reverse(path.begin(), path.end()); // 反转路径,使其从起点到终点
}
// 返回路径和总距离,如果不可达,总距离为-1
return {path, dist[end] == INT_MAX ? -1 : dist[end]};
}
// 导航对话框的消息处理函数
INT_PTR CALLBACK NaviDlgProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp) {
switch (msg) {
case WM_INITDIALOG: {
// 初始化起点/终点下拉框
HWND hComboStart = GetDlgItem(hDlg, IDC_COMBO_START);
HWND hComboEnd = GetDlgItem(hDlg, IDC_COMBO_END);
// 向下拉框添加地点选项
for (const auto& entry : PlaceNames) {
SendMessage(hComboStart, CB_ADDSTRING, 0, (LPARAM)entry.second.c_str());
SendMessage(hComboEnd, CB_ADDSTRING, 0, (LPARAM)entry.second.c_str());
}
// 默认选择第一个选项
SendMessage(hComboStart, CB_SETCURSEL, 0, 0);
SendMessage(hComboEnd, CB_SETCURSEL, 1, 0);
return TRUE;
}
case WM_COMMAND: {
if (LOWORD(wp) == IDC_BTN_QUERY) {
// 点击“查询路径”按钮
HWND hComboStart = GetDlgItem(hDlg, IDC_COMBO_START);
HWND hComboEnd = GetDlgItem(hDlg, IDC_COMBO_END);
HWND hEditPath = GetDlgItem(hDlg, IDC_EDIT_PATH);
// 获取选择的起点/终点索引
int startIdx = SendMessage(hComboStart, CB_GETCURSEL, 0, 0);
int endIdx = SendMessage(hComboEnd, CB_GETCURSEL, 0, 0);
if (startIdx == CB_ERR || endIdx == CB_ERR) {
MessageBox(hDlg, L"请选择起点和终点!", L"提示", MB_ICONINFORMATION);
return TRUE;
}
// 转换为CampusPlace枚举
CampusPlace start = (CampusPlace)startIdx;
CampusPlace end = (CampusPlace)endIdx;
// 计算最短路径
auto [path, totalTime] = DijkstraShortestPath(start, end);
if (path.empty() || totalTime == INT_MAX) {
SetWindowText(hEditPath, L"无法到达该地点!");
return TRUE;
}
// 格式化路径文本
std::wstringstream ss;
ss << L"最短路径(步行约" << totalTime << L"分钟):\n";
for (size_t i = 0; i < path.size(); ++i) {
ss << PlaceNames.at(path[i]);
if (i != path.size() - 1) ss << L" → ";
}
SetWindowText(hEditPath, ss.str().c_str());
return TRUE;
}
// 处理关闭/取消按钮
else if (LOWORD(wp) == IDOK || LOWORD(wp) == IDCANCEL) {
EndDialog(hDlg, LOWORD(wp));
return TRUE;
}
break;
}
case WM_CLOSE: {
EndDialog(hDlg, IDCANCEL);
return TRUE;
}
}
return FALSE;
}
int APIENTRY wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int) {
// 1. 显示登录对话框
INT_PTR nLoginResult = DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), nullptr, LoginDlgProc);
// 2. 如果登录成功(点击“确定”),显示主界面
if (nLoginResult == IDOK) {
INT_PTR nMainResult = DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG2), nullptr, MainDlgProc);
// 3. 如果主界面点击“确定”,显示导航界面
if (nMainResult == IDOK) {
DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG3), nullptr, NaviDlgProc);
}
}
// 所有界面关闭后,程序退出
return 0;
}在这段程序上添加哈夫曼编码和解码 和走迷宫(图的遍历算法)
最新发布