HDU 2112 HDU Today (最短路)
题目
经过锦囊相助,海东集团终于度过了危机,从此,HDU的发展就一直顺风顺水,到了2050年,集团已经相当规模了,据说进入了钱江肉丝经济开发区500强。这时候,XHD夫妇也退居了二线,并在风景秀美的诸暨市浬浦镇陶姚村买了个房子,开始安度晚年了。
这样住了一段时间,徐总对当地的交通还是不太了解。有时很郁闷,想去一个地方又不知道应该乘什么公交车,在什么地方转车,在什么地方下车(其实徐总自己有车,却一定要与民同乐,这就是徐总的性格)。
徐总经常会问蹩脚的英文问路:“Can you help me?”。看着他那迷茫而又无助的眼神,热心的你能帮帮他吗?
请帮助他用最短的时间到达目的地(假设每一路公交车都只在起点站和终点站停,而且随时都会开)。
Input
输入数据有多组,每组的第一行是公交车的总数N(0<=N<=10000);
第二行有徐总的所在地start,他的目的地end;
接着有n行,每行有站名s,站名e,以及从s到e的时间整数t(0<t<100)(每个地名是一个长度不超过30的字符串)。
note:一组数据中地名数不会超过150个。
如果N==-1,表示输入结束。
Output
如果徐总能到达目的地,输出最短的时间;否则,输出“-1”。
Sample Input
6 xiasha westlake xiasha station 60 xiasha ShoppingCenterofHangZhou 30 station westlake 20 ShoppingCenterofHangZhou supermarket 10 xiasha supermarket 50 supermarket westlake 10 -1
Sample Output
50
题解
本题通过地名(string)来描述点,而我们通常需要使用数字来进行操作,这时候就需要用到map。map<string, int> 可以帮我们查询输入的地名先前是否已经输入,若之前没有输入过,则通过mp[name] = cnt++,将地名与其编号关联起来形成映射。在得到了地名与其编号的关系后,就进行加边的操作,之后就是板子了。
注意点:
1.多组数据,每次程序开始的时候应该清空所有的vector,否则之前的数据还会存留在vector中,导致wa
2.map通过下标访问时是无法判断是否越界的,所以应该使用map中的find函数,若key不存在,则会返回mp.end(),所以在判断语句中只需要判断是否等于mp.end()就好了,等于就是该key值并不存在,需要与编号进行映射。
3.题目中有说存在不联通的情况,但由于我的疏忽导致wa了半天,以后要认真读题
AC代码
#include <iostream> #include <queue> #include <utility> #include <algorithm> #include <vector> #include <map> using namespace std; const int INF = 0x3f3f3f3f; struct edge{ int to, cost; edge(int _to, int _cost):to(_to), cost(_cost){} }; typedef pair<int, int> node; map<string, int> mp; vector<edge> G[155]; int dis[155]; void dij(int k){ dis[k] = 0; priority_queue<node, vector<node> ,greater<node> > q; q.push(node(0, k)); while(!q.empty()){ node temp = q.top(); q.pop(); if(temp.first > dis[temp.second]) continue; for(int i = 0; i < G[temp.second].size(); ++i){ edge e = G[temp.second][i]; if(e.cost + temp.first < dis[e.to]){ dis[e.to] = e.cost + temp.first; q.push(node(dis[e.to], e.to)); } } } } int main(){ ios::sync_with_stdio(0); cin.tie(0); int n; string a, b; int c; int cnt; string s, e; while(cin >> n){ if(n == -1) break; mp.clear(); for(int i = 0; i < 155; ++i) G[i].clear(); cnt = 0; cin >> s >> e; mp[s] = cnt++; if(mp.find(e) == mp.end()) mp[e] = cnt++; //终点起点可能是同一个 while(n--){ cin >> a >> b >> c; if(mp.find(a) == mp.end()) mp[a] = cnt++; if(mp.find(b) == mp.end()) mp[b] = cnt++; G[mp[a]].push_back(edge(mp[b], c)); G[mp[b]].push_back(edge(mp[a], c)); } fill(dis, dis + 155, INF); dij(mp[s]); if(dis[mp[e]] != INF) //可能到不了 cout << dis[mp[e]] << endl; else cout << -1 << endl; } return 0; }