当前位置: 代码迷 >> 综合 >> 地铁换乘—华为2014校招机试样题 —Dijkstra 和 Floyd-Warshall 算法解决
  详细解决方案

地铁换乘—华为2014校招机试样题 —Dijkstra 和 Floyd-Warshall 算法解决

热度:56   发布时间:2024-01-20 10:50:01.0

地铁换乘——华为2014校招机试样题

——方法一:Dijkstra最短路径算法

 

原题如下:

地铁换乘

描述:  

已知2条地铁线路,其中A为环线,B为东西向线路,线路都是双向的。经过的站点名分别如下,两条线交叉的换乘点用T1、T2表示。编写程序,任意输入两个站点名称,输出乘坐地铁最少需要经过的车站数量(含输入的起点和终点,换乘站点只计算一次)。

地铁线A(环线)经过车站:A1 A2 A3 A4 A5 A6 A7 A8 A9 T1 A10A11 A12 A13 T2 A14 A15 A16 A17 A18

地铁线B(直线)经过车站:B1 B2 B3 B4 B5 T1 B6 B7 B8 B9 B10T2 B11 B12 B13 B14 B15

运行时间限制:   无限制

内存限制:   无限制

输入:   输入两个不同的站名

输出:   输出最少经过的站数,含输入的起点和终点,换乘站点只计算一次

样例输入:   A1 A3

样例输出:   3

 


上星期试着解这道题,当时还没看数据结构图的部分,想着用双链表加上各种条件判断来解决,发现太复杂了,遂网上搜了搜,这里提供了一种通过图来解决的Floyed算法,链接如下:

http://blog.csdn.net/arcsinsin/article/details/11267755

鉴于此,这几天赶紧去看了下图的部分,刚看了Dijkstra单源点到所有终点的最短路径算法,想来可以改造下解决这里的问题,遂解决如下。

关于Dijkstra算法可以参见这里:

http://www.cnblogs.com/dolphin0520/archive/2011/08/26/2155202.html

 

#include <iostream>
#include <string>
#include <stack>
using namespace std;#define SIZE_A 21
#define SIZE_B 17#define N 35// 20 + 1
string A[] = {"A1","A2","A3","A4","A5","A6","A7","A8","A9","T1","A10","A11","A12","A13","T2","A14","A15","A16","A17","A18","A1"};
// 17
string B[] = {"B1","B2","B3","B4","B5","T1","B6","B7","B8","B9","B10","T2","B11","B12","B13","B14","B15"}; 
// 35
string Node[] = {"A1","A2","A3","A4","A5","A6","A7","A8","A9","T1","A10","A11","A12","A13","T2","A14","A15","A16","A17","A18","B1","B2","B3","B4","B5","B6","B7","B8","B9","B10","B11","B12","B13","B14","B15"}; struct Graph {int matrix[N][N];int n;int e;
};Graph g;
bool s[N];
int dist[N];
int path[N];int length=0;string StrBegin,StrEnd;void Dijkstra(int v0, int v1);int GetPos(string *array, string & str)
{int n=0;if (str[0] == 'B') {n+=20;array+=20;}if (str == "T1") return 9;if (str == "T2") return 14;while (*array != str) {array ++;n++;}return n;
}void BuildGraph()
{// 初始化matrixfor (int i=0; i<N; i++){for (int j=0; j<N; j++){g.matrix[i][j]=0;}}// 根据A建立边信息for (int i=0; i<(SIZE_A-1); i++){int u = GetPos(Node,A[i]);int v = GetPos(Node,A[i+1]);g.matrix[u][v]=1;g.matrix[v][u]=1;}// 根据B建立边信息for (int i=0; i<(SIZE_B-1); i++){int u = GetPos(Node,B[i]);int v = GetPos(Node,B[i+1]);g.matrix[u][v]=1;g.matrix[v][u]=1;}int u = GetPos(Node,StrBegin);int v = GetPos(Node,StrEnd);Dijkstra(u,v);}void Dijkstra(int v0, int v1)
{// 1、初始化for (int i=0; i<N; i++) {s[i] = false;if (g.matrix[v0][i] != 0){dist[i] = g.matrix[v0][i];path[i] = v0;}else{dist[i] = INT_MAX;path[i] = -1;}}s[v0]=true;dist[v0]=0;path[v0]=v0;// 2、循环n-1次for (int i=0; i<(N-1); i++){// 2.1、取dist[u]最小的uint min=INT_MAX;int u;for (int j=0; j<N; j++){if (s[j] == false && dist[j] < min){min = dist[j];u = j;}}s[u] = true;// 2.2、更新u邻接的所有wfor (int w=0; w<N; w++){if (s[w] == false && g.matrix[u][w] != 0){if (dist[u] + g.matrix[u][w] < dist[w]){dist[w] = dist[u] + g.matrix[u][w];path[w] = u;}}}}// 3、获取结果while (v1 != v0){v1 = path[v1];length++;}length ++; //stack<int> s;//while (v1 != v0)//{//	s.push(v1);//	v1 = path[v1];//}//s.push(v0);//while (!s.empty())//{//	length++;//	if (1)	// debug//	{//		int pos = s.top();//		string str = Node[pos];//		str += "\0";//		cout<<str<<" ";//	}//	s.pop();//}
}int main()
{//while(0){length = 0;cin>>StrBegin>>StrEnd;if (StrBegin == StrEnd)cout<<"1"<<endl;else{BuildGraph();cout<<length<<endl;}	system("pause");}return 0;
}


 ——方法二:Floyd-Warshall顶点对最短路径算法

该算法可以求出各顶点对之间的最短路径,写法简单,主要核心就是一个三层嵌套循环即可。


#include <iostream>
#include <string>
#include <stack>
using namespace std;#define SIZE_A 21
#define SIZE_B 17#define N 35
#define INF 0xfffff// 20 + 1
string A[] = {"A1","A2","A3","A4","A5","A6","A7","A8","A9","T1","A10","A11","A12","A13","T2","A14","A15","A16","A17","A18","A1"};
// 17
string B[] = {"B1","B2","B3","B4","B5","T1","B6","B7","B8","B9","B10","T2","B11","B12","B13","B14","B15"}; 
// 35
string Node[] = {"A1","A2","A3","A4","A5","A6","A7","A8","A9","T1","A10","A11","A12","A13","T2","A14","A15","A16","A17","A18","B1","B2","B3","B4","B5","B6","B7","B8","B9","B10","B11","B12","B13","B14","B15"}; int matrix[N][N];int dist[N][N];
int path[N][N];int length=0;string StrBegin,StrEnd;void Floyd_Warshall();int GetPos(string *array, string & str)
{int n=0;if (str[0] == 'B') {n+=20;array+=20;}if (str == "T1") return 9;if (str == "T2") return 14;while (*array != str) {array ++;n++;}return n;
}void BuildGraph()
{// 初始化matrixfor (int i=0; i<N; i++){for (int j=0; j<N; j++){matrix[i][j]=0;}}// 根据A建立边信息for (int i=0; i<(SIZE_A-1); i++){int u = GetPos(Node,A[i]);int v = GetPos(Node,A[i+1]);matrix[u][v]=1;matrix[v][u]=1;}// 根据B建立边信息for (int i=0; i<(SIZE_B-1); i++){int u = GetPos(Node,B[i]);int v = GetPos(Node,B[i+1]);matrix[u][v]=1;matrix[v][u]=1;}int u = GetPos(Node,StrBegin);int v = GetPos(Node,StrEnd);Floyd_Warshall();}void Floyd_Warshall()
{// 1、初始化for (int i=0; i<N; i++){for (int j=0; j<N; j++){if( i != j && matrix[i][j] > 0){dist[i][j] = matrix[i][j];path[i][j] = i;}else{dist[i][j] = INF;path[i][j] = -1;}}}// 2、Floyd核心三层循环for (int k=0; k<N; k++){for (int i=0; i<N; i++){for (int j=0; j<N; j++){if (dist[i][j] > dist[i][k] + dist[k][j]){dist[i][j] = dist[i][k] + dist[k][j];path[i][j] = path[k][j];}}}}// 3、输出结果int u = GetPos(Node,StrBegin);int v = GetPos(Node,StrEnd);while (u != v){v = path[u][v];length++;}length ++; 
}int main()
{//while(0){length = 0;cin>>StrBegin>>StrEnd;if (StrBegin == StrEnd)cout<<"1"<<endl;else{BuildGraph();cout<<length<<endl;}	system("pause");}return 0;
}



 

  相关解决方案