Return最小生成树中两个节点之间的路径
Return the path between two nodes in a minimum spanning tree
我有一个使用 Kruskal 算法创建的最小生成树存储在 key:string 和 data:set(字符串)
的映射中
mst = { "A" : ["B"]
"B" : ["A", "C", "D"]
"C" : ["B"]
"D" : ["B", "E"]
"E" : ["D", "F"] }
我正在尝试编写一个算法,它将 return 指定起始节点和结束节点之间的路径
$ findPath A F
> A B D E F
$ findPath F C
> F E D B C
我想我应该使用某种修改后的深度优先搜索,但我不确定如何实现该算法或如何存储构成路径的节点。我认为我不必担心将节点标记为 "visited" 因为 MST 中没有循环。
有一些类似的问题,但我还没有找到任何可以应用于我的特定场景的问题,它们似乎只处理非 MST,并且只有 return 如果路径可以在两个节点之间找到,在我的例子中,我已经知道每个节点之间都有一条路径,我还需要路径上的节点列表。
编辑
答案转换为 C++,可能不是最干净的代码,但它有效
vector<string> findPath(map<string, set<string>> mst, string src, string dest, vector<string> path) {
if(src == dest) {
return path;
}
set<string> possible = mst[src];
for(vector<string>::iterator it = path.begin(); it != path.end(); it++) {
if(possible.find(*it) != possible.end())
possible.erase(*it);
}
for(set<string>::iterator it = possible.begin(); it != possible.end(); it++) {
vector<string> a = path;
if(find(a.begin(), a.end(), src) == a.end())
a.push_back(src);
vector<string> p = findPath(mst, *it, dest, a);
if(p[0] != "FALSEBEGINNING") {
return p;
}
}
vector<string> p = path;
p[0] = "FALSEBEGINNING";
return p;
}
const mst = {
A: ['B'],
B: ['A', 'C', 'D'],
C: ['B'],
D: ['B', 'E'],
E: ['D', 'F']
}
const findPathTraversal = (mst, src, dest, path) => {
const findPath = (mst, src, dest, path) => {
if (src === dest) return path
let possible = mst[src]
possible = possible.filter(v => !path.includes(v))
for (let i = 0; i < possible.length; i++) {
let a = path
if (!a.includes(src)) a.push(src)
let p = findPath(mst, possible[i], dest, a)
if (p != -1) return path
}
return -1
}
let ans = findPath(mst, src, dest, path)
ans.push(dest)
return ans
}
console.log(findPathTraversal(mst, 'A', 'F', []))
我有一个使用 Kruskal 算法创建的最小生成树存储在 key:string 和 data:set(字符串)
的映射中mst = { "A" : ["B"]
"B" : ["A", "C", "D"]
"C" : ["B"]
"D" : ["B", "E"]
"E" : ["D", "F"] }
我正在尝试编写一个算法,它将 return 指定起始节点和结束节点之间的路径
$ findPath A F
> A B D E F
$ findPath F C
> F E D B C
我想我应该使用某种修改后的深度优先搜索,但我不确定如何实现该算法或如何存储构成路径的节点。我认为我不必担心将节点标记为 "visited" 因为 MST 中没有循环。
有一些类似的问题,但我还没有找到任何可以应用于我的特定场景的问题,它们似乎只处理非 MST,并且只有 return 如果路径可以在两个节点之间找到,在我的例子中,我已经知道每个节点之间都有一条路径,我还需要路径上的节点列表。
编辑 答案转换为 C++,可能不是最干净的代码,但它有效
vector<string> findPath(map<string, set<string>> mst, string src, string dest, vector<string> path) {
if(src == dest) {
return path;
}
set<string> possible = mst[src];
for(vector<string>::iterator it = path.begin(); it != path.end(); it++) {
if(possible.find(*it) != possible.end())
possible.erase(*it);
}
for(set<string>::iterator it = possible.begin(); it != possible.end(); it++) {
vector<string> a = path;
if(find(a.begin(), a.end(), src) == a.end())
a.push_back(src);
vector<string> p = findPath(mst, *it, dest, a);
if(p[0] != "FALSEBEGINNING") {
return p;
}
}
vector<string> p = path;
p[0] = "FALSEBEGINNING";
return p;
}
const mst = {
A: ['B'],
B: ['A', 'C', 'D'],
C: ['B'],
D: ['B', 'E'],
E: ['D', 'F']
}
const findPathTraversal = (mst, src, dest, path) => {
const findPath = (mst, src, dest, path) => {
if (src === dest) return path
let possible = mst[src]
possible = possible.filter(v => !path.includes(v))
for (let i = 0; i < possible.length; i++) {
let a = path
if (!a.includes(src)) a.push(src)
let p = findPath(mst, possible[i], dest, a)
if (p != -1) return path
}
return -1
}
let ans = findPath(mst, src, dest, path)
ans.push(dest)
return ans
}
console.log(findPathTraversal(mst, 'A', 'F', []))