实际代码中,我们使用哈希映射来实时维护「车站所属公交路线列表」。假设当前枚举到公交路线 i 中的车站 site,此时哈希映射中已记录若干条公交路线经过车站 site,我们只需要让点 i 与这些点公交路线对应的点相连即可。完成了连线后,我们再将公交路线 i 加入到「车站 site 所属公交路线列表」中。
publicclassSolution { publicintNumBusesToDestination(int[][] routes, int source, int target) { if (source == target) { return0; }
int n = routes.Length; bool[,] edge = newbool[n, n]; Dictionary<int, IList<int>> rec = new Dictionary<int, IList<int>>(); for (int i = 0; i < n; i++) { foreach (int site in routes[i]) { IList<int> list = new List<int>(); if (rec.ContainsKey(site)) { list = rec[site]; foreach (int j in list) { edge[i, j] = edge[j, i] = true; } rec[site].Add(i); } else { list.Add(i); rec.Add(site, list); } } }
int[] dis = newint[n]; Array.Fill(dis, -1); Queue<int> que = new Queue<int>(); if (rec.ContainsKey(source)) { foreach (int bus in rec[source]) { dis[bus] = 1; que.Enqueue(bus); } } while (que.Count > 0) { int x = que.Dequeue(); for (int y = 0; y < n; y++) { if (edge[x, y] && dis[y] == -1) { dis[y] = dis[x] + 1; que.Enqueue(y); } } }
int ret = int.MaxValue; if (rec.ContainsKey(target)) { foreach (int bus in rec[target]) { if (dis[bus] != -1) { ret = Math.Min(ret, dis[bus]); } } } return ret == int.MaxValue ? -1 : ret; } }
var numBusesToDestination = function(routes, source, target) { if (source === target) { return0; }
const n = routes.length; const edge = newArray(n).fill(0).map(() =>newArray(n).fill(0)); const rec = newMap(); for (let i = 0; i < n; i++) { for (const site of routes[i]) { const list = (rec.get(site) || []); for (const j of list) { edge[i][j] = edge[j][i] = true; } list.push(i); rec.set(site, list); } }
const dis = newArray(n).fill(-1); const que = []; for (const bus of (rec.get(source) || [])) { dis[bus] = 1; que.push(bus); } while (que.length) { const x = que.shift(); for (let y = 0; y < n; y++) { if (edge[x][y] && dis[y] === -1) { dis[y] = dis[x] + 1; que.push(y); } } }
let ret = Number.MAX_VALUE; for (const bus of (rec.get(target) || [])) { if (dis[bus] !== -1) { ret = Math.min(ret, dis[bus]); } } return ret === Number.MAX_VALUE ? -1 : ret; };
n := len(routes) edge := make([][]bool, n) for i := range edge { edge[i] = make([]bool, n) } rec := map[int][]int{} for i, route := range routes { for _, site := range route { for _, j := range rec[site] { edge[i][j] = true edge[j][i] = true } rec[site] = append(rec[site], i) } }
dis := make([]int, n) for i := range dis { dis[i] = -1 } q := []int{} for _, bus := range rec[source] { dis[bus] = 1 q = append(q, bus) } forlen(q) > 0 { x := q[0] q = q[1:] for y, b := range edge[x] { if b && dis[y] == -1 { dis[y] = dis[x] + 1 q = append(q, y) } } }
ans := math.MaxInt32 for _, bus := range rec[target] { if dis[bus] != -1 && dis[bus] < ans { ans = dis[bus] } } if ans < math.MaxInt32 { return ans } return-1 }
intnumBusesToDestination(int** routes, int routesSize, int* routesColSize, int source, int target) { if (source == target) { return0; }
int n = routesSize; int edge[n][n]; memset(edge, 0, sizeof(edge)); structVectorrec[100001]; for (int i = 0; i < 100001; i++) { init(&rec[i]); } for (int i = 0; i < n; i++) { for (int j = 0; j < routesColSize[i]; j++) { int site = routes[i][j]; for (int k = 0; k < rec[site].size; k++) { edge[i][rec[site].arr[k]] = edge[rec[site].arr[k]][i] = true; } push_back(&rec[site], i); } } int dis[n]; memset(dis, -1, sizeof(dis)); int que[n]; int left = 0, right = 0;
for (int i = 0; i < rec[source].size; i++) { dis[rec[source].arr[i]] = 1; que[right++] = rec[source].arr[i]; } while (left < right) { int x = que[left++]; for (int y = 0; y < n; y++) { if (edge[x][y] && dis[y] == -1) { dis[y] = dis[x] + 1; que[right++] = y; } } }
int ret = INT_MAX;
for (int i = 0; i < rec[target].size; i++) { if (dis[rec[target].arr[i]] != -1) { ret = fmin(ret, dis[rec[target].arr[i]]); } } return ret == INT_MAX ? -1 : ret; }