最短路。很坑的是,这道题没说清楚是不是有向边(其实是无向边),而且还有起点和终点相同的数据。
两年前我写的是一个map<string,int>
和一个vector<string>
来对地名和下标双向关联,但是现在发现没必要了,只用一个map<string,int>
用来查重就行了,如果让你输出地名之类的才可能需要双向关联。
#include <iostream> #include <algorithm> #include <vector> #include <cstring> #include <map> #include <string> using namespace std; const int MAXN = 152; const int INF = 1e9; int M, S, T; map<string, int> m; int g[MAXN][MAXN]; int dis[MAXN]; bool vis[MAXN]; int cnt; void init() { memset(g, -1, sizeof g); m.clear(); memset(vis, 0, sizeof vis); fill(dis, dis + MAXN, INF); cnt = 0; } void dijkstra(int s) { dis[s] = 0; for (int i = 0; i < cnt; i++) { int u = -1, mind = INF; for (int j = 0; j < cnt; j++) { if (!vis[j] && dis[j] < mind) { mind = dis[j]; u = j; } } if (u == -1) return; vis[u] = 1; for (int j = 0; j < cnt; j++) { if (!vis[j] && g[u][j] != -1) { if (dis[u] + g[u][j] < dis[j]) dis[j] = dis[u] + g[u][j]; } } } } int main() { string a, b; // 如果地名带空格怎么办? int w; for (; ~scanf("%d", &M);) { if (M == -1) return 0; init(); cin >> a >> b; if (a == b) // 好无聊啊,还会有起始终止相同的情况 { //printf("0\n"); //break; 还真不能直接退,因为要等它输入完那几个公交车 m.insert(make_pair(a, S = T = cnt++)); } else { m.insert(make_pair(a, S = cnt++)); m.insert(make_pair(b, T = cnt++)); } for (; M--;) { cin >> a >> b >> w; if (m.find(a) == m.end()) m.insert(make_pair(a, cnt++)); if (m.find(b) == m.end()) m.insert(make_pair(b, cnt++)); int aid = m[a]; int bid = m[b]; if (g[aid][bid] == -1) g[aid][bid] = g[bid][aid] = w; // 公交车是往返开的 else g[aid][bid] = g[bid][aid] = min(g[aid][bid], w); } dijkstra(S); if (dis[T] != INF) printf("%d\n", dis[T]); else printf("-1\n"); } return 0; }
来源:https://www.cnblogs.com/CrossingOver/p/10704865.html