我获得了一个定向图,并且在其中给出了两个节点,我需要找到可以从两个节点到达的最近的节点。唯一的问题是我能用两个dfs做到这一点,但我被告知要在O(logn)中做到这一点。附加限制是每个单元格可以具有最多一个传出边缘。输入以大小为N的数组给出,其中数组中的eachentry表示此节点所指向的节点的索引。所以这是我尝试的代码(不完全是dfs但仍然):
int leastCommonDescendent(int nodes[], int N, int node1, int node2)
{
int *visited = new int [N];
int cnt1 = 0; //used for counting length of path from node1 to node2
int cnt2 = 0; //used for counting length of path from node2 to node1
int mark = node1; //storing as a marker needed later for detecting end of search
if(node1 == node2) return node2;
for(int i = 0; i < N; i++){
visited[i] = 0;
}
while((nodes[node1] != node1) && (nodes[node1] != -1) && (visited[node1] == 0) && (node1 != node2)){
visited[node1]++;
node1 = nodes[node1];
cnt1++;
}
visited[node1]++; //so that first node in cycle has count 2
//if find a node in 2nd iteration that has count 2
//such that when node1 == node2 it means we are in the same subgraph
//elsif node1 != node2 we are in different sub graphs
while((nodes[node2] != node2) && (nodes[node2] != -1) && (visited[node2] != 2) && (node1 != node2)){
visited[node2]++;
node2 = nodes[node2];
cnt2++;
}
//In below case the nodes are in different disjoint subgraphs
//and both subgraphs have loops so node1 can never be equal to node2
//cout << visited[node1] << visited[node2] << endl;
if(node1 != node2) return -1;
//In below case both nodes are in different disjoint subgraphs
//but there is no loop in 1st one(containing node1)
//and 2nd one has a loop
if ((nodes[node1] == -1) && (visited[node2] == 1)) return -1;
//In below case both nodes are in different disjoint subgraphs
//but 1st one has a loop and second one doesn't
if(nodes[node2] == -1) return -1;
//In below case both nodes are in same subgraph so we
//need to check the length of two alternate paths
if(cnt1 > cnt2)
return node2;
else
return mark;
}
在这种情况下,如果我想从7&amp;找到最近的节点9我得到答案9虽然它应该是8.虽然我明白这是因为我在两个循环中都有条件cell1!= cell2但是我要去整个循环以防我删除那些邀请更多时间。此外,我觉得这个解决方案混杂了多个if。我们能有更简单的解决方案吗? (可能 O(logn))
此图也可以具有如上图所示的周期。因此,我猜不可能转换为树。
答案 0 :(得分:1)
通过简单地反转图表的链接,可以很容易地将其缩小为(和来自)Lowest Common Ancestor in a tree(或准确地说是在森林中)。
一般情况下,可以在O(h)
中完成,步进&#34; up&#34;树一步一步(在原始图中前进),并将找到的节点存储在一个集合中,直到设置的相交不为空。
如果允许预处理,可以在线性时间预处理它以获得更好的弹性。