You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

421 lines
15 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <iostream>
#include <vector>
#include <queue>
#include <string>
#include <map>
using namespace std;
const int N = 240; //地铁站点数目
const int INF = 0x3f3f3f3f; //表示正无穷
//地铁线路的颜色
string line_color[22] = {"", "1号线", "2号线", "4号线",
"5号线", "6号线", "7号线",
"8号线", "9号线", "10号线",
"13号线", "14号线东",
"14号线西", "15号线",
"16号线", "八通线", "昌平线",
"亦庄线", "房山线", "机场线",
"西郊线", "S2线"};
//地铁站点信息
struct Station {
string name; //站点名称
int line; //所在地铁线路
int transfer; //是否为换乘站0不是否则表示该站可以换乘
bool operator<(const Station& other) const { //定义小于号方便使用stl的heap/priority_queue
return line < other.line;
}
} station_list[N + 1];
//地铁站点间的距离
int dist[N + 1][N + 1];
//向地铁站点列表中添加站点
void add_station(int id, string name, int line, int transfer) {
station_list[id] = {name, line, transfer};
}
//初始化北京地铁的站点信息和站点间距离
void init_subway_map() {
//初始化站点信息
add_station(1, "苹果园", 1, 1);
add_station(2, "古城", 1, 0);
add_station(3, "八角游乐园", 1, 0);
add_station(4, "八宝山", 1, 0);
add_station(5, "玉泉路", 1, 0);
add_station(6, "五棵松", 1, 1);
add_station(7, "万寿路", 1, 0);
add_station(8, "公主坟", 1, 1);
add_station(9, "军事博物馆", 1, 0);
add_station(10, "木樨地", 1, 0);
add_station(11, "南礼士路", 1, 0);
add_station(12, "复兴门", 1, 1);
add_station(13, "西单", 1, 1);
add_station(14, "天安门西", 1, 0);
add_station(15, "天安门东", 1, 0);
add_station(16, "王府井", 1, 1);
add_station(17, "东单", 1, 1);
add_station(18, "建国门", 1, 1);
add_station(19, "永安里", 1, 0);
add_station(20, "国贸", 1, 1);
add_station(21, "大望路", 1, 0);
add_station(22, "四惠", 1, 1);
add_station(23, "四惠东", 1, 0);
add_station(24, "西直门", 2, 1);
add_station(25, "车公庄", 2, 1);
add_station(26, "阜成门", 2, 0);
add_station(27, "复兴门", 2, 1);
add_station(28, "长椿街", 2, 0);
add_station(29, "宣武门", 2, 1);
add_station(30, "和平门", 2, 0);
add_station(31, "前门", 2, 0);
add_station(32, "崇文门", 2, 1);
add_station(33, "北京站", 2, 1);
add_station(34, "建国门", 2, 1);
add_station(35, "朝阳门", 2, 1);
add_station(36, "东四十条", 2, 0);
add_station(37, "东直门", 2, 1);
add_station(38, "雍和宫", 2, 1);
add_station(39, "安定门", 2, 0);
add_station(40, "鼓楼大街", 2, 1);
add_station(41, "积水潭", 2, 0);
add_station(42, "西直门", 4, 1);
add_station(43, "新街口", 4, 0);
add_station(44, "平安里", 4, 1);
add_station(45, "西四", 4, 0);
add_station(46, "灵境胡同", 4, 0);
add_station(47, "西单", 4, 1);
add_station(48, "宣武门", 4, 1);
add_station(49, "菜市口", 4, 1);
add_station(50, "陶然亭", 4, 0);
add_station(51, "北京南站", 4, 1);
add_station(52, "马家堡", 4, 0);
add_station(53, "角门西", 4, 0);
add_station(54, "公益西桥", 4, 0);
add_station(55, "新宫", 4, 0);
add_station(56, "西红门", 4, 0);
add_station(57, "高米店北", 4, 0);
add_station(58, "高米店南", 4, 0);
add_station(59, "枣园", 4, 0);
add_station(60, "清源路", 4, 0);
add_station(61, "黄村西大街", 4, 0);
add_station(62, "黄村火车站", 4, 0);
add_station(63, "义和庄", 4, 0);
add_station(64, "生物医药基地", 4, 0);
add_station(65, "天宫院", 4, 0);
add_station(66, "宋家庄", 5, 1);
add_station(67, "刘家窑", 5, 0);
add_station(68, "蒲黄榆", 5, 1);
add_station(69, "天坛东门", 5, 0);
add_station(70, "磁器口", 5, 1);
add_station(71, "崇文门", 5, 1);
add_station(72, "东单", 5, 1);
add_station(73, "灯市口", 5, 0);
add_station(74, "东四", 5, 0);
add_station(75, "张自忠路", 5, 0);
add_station(76, "北新桥", 5, 0);
add_station(77, "雍和宫", 5, 1);
add_station(78, "和平里北街", 5, 0);
add_station(79, "和平西桥", 5, 0);
add_station(80, "惠新西街南口", 5, 0);
add_station(81, "惠新西街北口", 5, 0);
add_station(82, "大屯路东", 5, 1);
add_station(83, "北苑路北", 5, 0);
add_station(84, "立水桥南", 5, 0);
add_station(85, "立水桥", 5, 1);
add_station(86, "天通苑南", 5, 0);
add_station(87, "天通苑", 5, 0);
add_station(88, "天通苑北", 5, 0);
add_station(89, "昌平西山口", 5, 0);
add_station(90, "十三陵景区", 5, 0);
add_station(91, "昌平", 5, 0);
add_station(92, "昌平东关", 5, 0);
add_station(93, "南邵", 8, 0);
add_station(94, "沙河高教园", 8, 0);
add_station(95, "沙河", 8, 0);
add_station(96, "巩华城", 8, 0);
add_station(97, "朱辛庄", 8, 0);
add_station(98, "生命科学园", 8, 0);
add_station(99, "西二旗", 13, 1);
add_station(100, "生命科学园", 13, 0);
add_station(101, "永泰庄", 13, 0);
add_station(102, "西北旺", 13, 0);
add_station(103, "马连洼", 13, 0);
add_station(104, "上地", 13, 1);
add_station(105, "五道口", 13, 1);
add_station(106, "知春路", 13, 1);
add_station(107, "知春里", 13, 0);
add_station(108, "海淀黄庄", 4, 1);
add_station(109, "人民大学", 4, 0);
add_station(110, "魏公村", 4, 0);
add_station(111, "国家图书馆", 4, 1);
add_station(112, "动物园", 4, 1);
add_station(113, "新街口", 4, 0);
add_station(114, "平安里", 6, 1);
add_station(115, "北海北", 6, 0);
add_station(116, "南锣鼓巷", 6, 1);
add_station(117, "东四", 6, 1);
add_station(118, "朝阳门", 6, 1);
add_station(119, "东大桥", 6, 0);
add_station(120, "呼家楼", 6, 1);
add_station(121, "金台路", 6, 1);
add_station(122, "十里堡", 6, 0);
add_station(123, "青年路", 6, 0);
add_station(124, "褡裢坡", 6, 0);
add_station(125, "黄渠", 6, 0);
add_station(126, "常营", 6, 0);
add_station(127, "草房", 6, 0);
add_station(128, "物资学院路", 6, 0);
add_station(129, "通州北关", 6, 0);
add_station(130, "北运河西", 6, 0);
add_station(131, "郝家府", 6, 0);
add_station(132, "东夏园", 6, 0);
add_station(133, "潞城", 6, 0);
add_station(134, "顺义", BC, 0);
add_station(135, "俸伯", BC, 0);
add_station(136, "机场北站", BC, 0);
add_station(137, "中关村", 10, 1);
add_station(138, "海淀大街", 10, 1);
add_station(139, "知春路", 10, 1);
add_station(140, "西土城", 10, 0);
add_station(141, "牡丹园", 10, 0);
add_station(142, "健德门", 10, 0);
add_station(143, "北土城", 10, 0);
add_station(144, "安贞门", 10, 1);
add_station(145, "惠新西街南口", 10, 0);
add_station(146, "芍药居", 10, 1);
add_station(147, "太阳宫", 10, 0);
add_station(148, "三元桥", 10, 1);
add_station(149, "亮马桥", 10, 0);
add_station(150, "农业展览馆", 10, 1);
add_station(151, "团结湖", 10, 0);
add_station(152, "呼家楼", 10, 1);
add_station(153, "金台夕照", 10, 0);
add_station(154, "国贸", 10, 1);
add_station(155, "双井", 10, 0);
add_station(156, "劲松", 10, 0);
add_station(157, "潘家园", 10, 0);
add_station(158, "十里河", 10, 1);
add_station(159, "分钟寺", 10, 0);
add_station(160, "成寿寺", 10, 0);
add_station(161, "宋家庄", 10, 1);
add_station(162, "石榴庄", 5, 0);
add_station(163, "大红门", 10, 0);
add_station(164, "角门东", 10, 0);
add_station(165, "角门西", 10, 0);
add_station(166, "草桥", 10, 0);
add_station(167, "纪家庙", FS, 0);
add_station(168, "首经贸", FS, 1);
add_station(169, "丰台站", FS, 0);
add_station(170, "泥洼", FS, 0);
add_station(171, "西局", FS, 1);
add_station(172, "六里桥", FS, 1);
add_station(173, "莲花桥", FS, 0);
add_station(174, "公主坟", FS, 1);
add_station(175, "西钓鱼台", FS, 0);
add_station(176, "慈寿寺", FS, 1);
add_station(177, "车道沟", FS, 0);
add_station(178, "长春桥", FS, 0);
add_station(179, "火器营", 9, 1);
add_station(180, "巴沟", 10, 0);
add_station(181, "苏州街", 10, 0);
add_station(182, "海淀五路居", 10, 0);
add_station(183, "知春路", 10, 1);
add_station(184, "知春里", 10, 0);
add_station(185, "西土城", 10, 0);
add_station(186, "牡丹园", 10, 0);
add_station(187, "健德门", 10, 0);
add_station(188, "北土城", 10, 0);
add_station(189, "安贞门", 10, 0);
//初始化站点间距离
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
if (i == j) {
dist[i][j] = 0;
} else {
dist[i][j] = INF;
}
}
}
//1号线
dist[1][2] = dist[2][1] = 4;
dist[2][3] = dist[3][2] = 4;
//2号线
dist[4][5] = dist[5][4] = 4;
dist[5][6] = dist[6][5] = 4;
//4号线
dist[7][8] = dist[8][7] = 6;
dist[8][9] = dist[9][8] = 6;
//5号线
dist[10][11] = dist[11][10] = 4;
dist[11][12] = dist[12][11] = 4;
//6号线
dist[13][14] = dist[14][13] = 4;
dist[14][15] = dist[15][14] = 4;
//7号线
dist[16][17] = dist[17][16] = 5;
dist[17][18] = dist[18][17] = 5;
//8号线
dist[19][20] = dist[20][19] = 4;
dist[20][21] = dist[21][20] = 4;
//9号线
dist[22][23] = dist[23][22] = 5;
dist[23][24] = dist[24][23] = 5;
//10号线
dist[25][26] = dist[26][25] = 4;
dist[26][27] = dist[27][26] = 4;
//13号线
dist[28][29] = dist[29][28] = 6;
dist[29][30] = dist[30][29] = 6;
//14号线东
dist[31][32] = dist[32][31] = 5;
dist[32][33] = dist[33][32] = 5;
//14号线西
dist[34][35] = dist[35][34] = 6;
dist[35][36] = dist[36][35] = 6;
//15号线
dist[37][38] = dist[38][37] = 3;
dist[38][39] = dist[39][38] = 3;
//16号线
dist[40][41] = dist[41][40] = 3;
//八通线
dist[42][43] = dist[43][42] = 3;
dist[43][44] = dist[44][43] = 4;
//昌平线
dist[45][46] = dist[46][45] = 4;
dist[46][47] = dist[47][46] = 4;
//亦庄线
dist[48][49] = dist[49][48] = 3;
//房山线
dist[50][51] = dist[51][50] = 3;
dist[51][52] = dist[52][51] = 3;
//机场线
dist[53][54] = dist[54][53] = 13;
//西郊线(只有一个站点)
dist[55][55] = 10;
//S2线
dist[56][57] = dist[57][56] = 4;
dist[57][58] = dist[58][57] = 4;
}
//BFS搜索最短路径返回路径长度
int bfs(int start, int end) {
queue<int> q;
vector<bool> visited(N + 1, false); //记录每个节点是否被访问过
vector<int> distance(N + 1); //记录每个节点距离起点的距离
q.push(start);
visited[start] = true;
while (!q.empty()) {
int cur = q.front();
q.pop();
for (int i = 1; i <= N; i++) {
if (dist[cur][i] != INF && !visited[i]) {
visited[i] = true;
distance[i] = distance[cur] + 1;
q.push(i);
}
}
}
return distance[end];
}
//输出从start到end的最短路径
void print_route(int start, int end) {
priority_queue<pair<int,string>, vector<pair<int,string>>, greater<pair<int,string>>> q; //小根堆,按照距离升序排列,如果距离相同,按照站点名称升序排列
map<int, bool> added; //记录已经添加到队列中的节点,防止重复添加
vector<pair<int,string>> route; //记录路径上的所有站点
q.push({0,station_list[start].name});
while (!q.empty()) {
auto cur = q.top();
q.pop();
if (cur.second == station_list[end].name) { //找到了终点,直接退出循环
break;
}
int cur_id = 0;
for (int i = 1; i <= N; i++) {
if (station_list[i].name == cur.second) {
cur_id = i;
break;
}
}
added[cur_id] = true;
for (int i = 1; i <= N; i++) {
if (dist[cur_id][i] != INF && !added[i]) { //如果两个站点之间有直达的地铁线路,并且该站点没有被添加过
q.push({cur.first + dist[cur_id][i], station_list[i].name}); //将该节点加入队列
added[i] = true;
route.push_back({i, station_list[i].name}); //记录该站点
}
}
}
cout << "从 " << station_list[start].name << " 到 " << station_list[end].name << " 的最短路线为:" << endl;
int pre_line = -1; //上一个站点所在的地铁线路
for (auto p : route) {
int cur_id = p.first;
int cur_line = station_list[cur_id].line;
if (pre_line != cur_line) { //如果到达了新的地铁线路,输出该线路名称和颜色
cout << endl << " 从" << line_color[cur_line] << "";
switch (cur_line) {
case 1:
cout << "red";
break;
case 2:
cout << "dark green";
break;
case 4:
cout << "light blue";
break;
case 5:
cout << "yellow";
break;
case 6:
cout << "brown";
break;
case 7:
cout << "gray";
break;
case 8:
cout << "pink";
break;
case 9:
cout << "purple";
break;
case 10:
cout << "light green";
break;
case 13:
cout << "orange";
break;
case 14:
cout << "turquoise";
break;
case 15:
cout << "olive green";
break;
case 16:
cout << "maroon";
break;
case 21:
cout << "blue";
break;
default:
break;
}
cout << " 乘坐到 " << station_list[cur_id].name << " 站,步行 ";
pre_line = cur_line;
} else {
cout << " -> ";
}
cout << dist[p.first][route.back().first] << " 米";
}
cout << endl << "共 " << bfs(start, end) << " 站,需要步行 " << route.back().first - route.front().first << " 米" << endl;
}
int main() {
init_subway_map();
print_route(1, 240);
return 0;
}