题目描述
样例描述
思路
图论 + Floyd
转化为图论的问题:给一个有向图,求任意两点之间的距离。题意说明没有矛盾,说明每两个点之间的距离是唯一的。Floyd就是求两个点之间的最短距离,本题就是距离
在这里插入图片描述
代码
class Solution {
public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
double d[][] = new double[50][50]; //d[a][b]表示a到b的距离
Map<String, Integer> map = new HashMap<>(); //将每个字符 映射 到一个顶点编号
int idx = 1; //总顶点数
//先统计总顶点数
for (List<String> list: equations) {
for (String s: list) {
if (!map.containsKey(s)) {
map.put(s, idx ++);
}
}
}
//将每个顶点到自身的距离设置为1, 因为 a/a = 1
for (int i = 1; i <= idx; i ++ ) {
for (int j = 1; j <= idx; j ++ ) {
if (i == j) {
d[i][j] = 1.0;
}
}
}
//将已知条件的边长 赋值到图中
for (int i = 0; i < equations.size(); i ++ ) {
//获取两个顶点编号
int x = map.get(equations.get(i).get(0));
int y = map.get(equations.get(i).get(1));
d[x][y] = values[i];
//反过来就是取倒数
d[y][x] = 1 / values[i];
}
//利用Floyd算法来求任意两个点的最短距离 (由题意是唯一距离),直接存在图中
//由于是唯一,所以只要能中转,就计算距离
for (int k = 1; k <= idx; k ++ ) {
for (int i = 1; i <= idx; i ++ ) {
for (int j = 1; j <= idx; j ++ ) {
//只要以k作为中转结点不为空,就取代
if (d[i][k] != 0 && d[k][j] != 0) {
d[i][j] = d[i][k] * d[k][j];
}
}
}
}
double res[] = new double[queries.size()];
int cnt = 0;
//根据查询来求结果
for (List<String> list: queries) {
int x = map.getOrDefault(list.get(0), 0);
int y = map.getOrDefault(list.get(1), 0);
//只要不存在某字符
if (x == 0 || y == 0) {
res[cnt ++] = -1.0;
}
//否则要判断是否存在该路径
else res[cnt ++] = (d[x][y] == 0 ? -1.0 : d[x][y]);
}
return res;
}
}