lgx
题目大意:
徐总坐车去目的地,他所在的地点是起点,目的地是终点,属于最短路径问题,但这次不是距离了,而是时间,道理是一样的。
解题思路:
还是还是使用迪杰斯特拉算法,本题输入的是地点不是编号,是字符,所以在算法的基础上增加一个转换的算法,将字符转换成编号,在通过迪杰斯特拉算法完成最短时间计算。
#include<stdio.h> #include<string.h> #define INF 1<<25 //INF最大值 //迪杰斯特拉法 const int N = 160; int w[N][N], d[N], m; char add[N][40]; void Init() //设置对角线为0是因为两个站点之间就没有距离 { for(int i = 0; i < 150; i++) { for(int j = 0; j < 150; j++) { if(i == j) { w[i][j] = 0; } else { w[i][j] = INF; } } } } int Change(char *s) //将站名转化为编号 返回编号 { int i; for(i = 0; i < m; i++) { if(strcmp(add[i], s) == 0) //add是存储站名的字符数组 ,s代表连续输入的s1和s2,是站名 { return i; } } if(i == m) //如果将s的站名给addm中,m++先改变,在修改返回m-1 { strcpy(add[m], s); m++; return m-1; } } void Dijkstra() { int vis[N], i; // memset(vis, 0, sizeof(vis)); //初始化 for(i = 0; i < m; i++) { d[i] = INF;//距离初始化为最大 } d[0] = 0; //第一个点的距离设置为0 for(i = 0; i < m; i++) { int x = 0, temp = INF;//x代表最短距离的位置,temp代表最短距离 for(int y = 0; y < m; y++) { if(!vis[y] && d[y] < temp)//如果y站没有访问且距离小于temp则继续进行 { x = y; temp = d[x];//多次循环找到最短的那个距离 } } if(temp == INF)//如果都访问完发现最小值为最大值则返回 { break; } vis[x] = 1;//将最短距离的那个点x标记为已经访问过 for(int y = 0; y < m; y++) { if( d[x] + w[x][y] < d[y])//如果当前点的距离加上下一个访问距离下小于下一个访问距离则将最短的访问距离给到下一个点 { d[y] = d[x] + w[x][y]; } } } } int main() { int n, i, j; while(scanf("%d",&n)!=EOF && n != -1) //输入数据组数 { Init(); //初始化 char st[40], ed[40], s1[40], s2[40]; int a, b, c; scanf("%s%s",st, ed);//输入起点和终点 strcpy(add[0], st); //将起点放在add0中 strcpy(add[1], ed); //将终点放在add1中 m = 2; //m为 for(i = 0; i < n; i++)//n为公交车总数量 { scanf("%s%s%d",s1, s2, &c); //站名s和站名e,两站间的时间t a = Change(s1); //将站名s转化为编号a b = Change(s2); //将站名e转化为编号b w[a][b] = w[b][a] = c; //将时间赋给map中 } if(strcmp(st, ed) == 0) //比较,如果起点和终点一样则strcmp输出0 { printf("0\n"); continue; //结束一次循环 } Dijkstra(); //迪杰斯特拉最短路径发 if(d[1] == INF)// 如果输出的时间是最大值,则输出-1,否则输出最短时间 { printf("-1\n"); } else { printf("%d\n",d[1]); } } return 0; }