Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 有向图中两个给定节点的最近会议节点_C++_Algorithm_Directed Graph - Fatal编程技术网

C++ 有向图中两个给定节点的最近会议节点

C++ 有向图中两个给定节点的最近会议节点,c++,algorithm,directed-graph,C++,Algorithm,Directed Graph,我得到一个有向图,其中有两个节点,我需要找到两个节点都能到达的最近节点。唯一的问题是我可以用两个dfs来做,但是我被告知用O(logn)来做。额外的限制是每个单元格最多只能有一条传出边。输入以大小为N的数组形式给出,其中数组中的每个元素表示该节点指向的节点的索引。因此,这是我尝试过的代码(不完全是dfs,但仍然): int-leastcommon子代(int-nodes[],int-N,int-node1,int-node2) { int*visted=新int[N]; int cnt1=0;/

我得到一个有向图,其中有两个节点,我需要找到两个节点都能到达的最近节点。唯一的问题是我可以用两个dfs来做,但是我被告知用O(logn)来做。额外的限制是每个单元格最多只能有一条传出边。输入以大小为N的数组形式给出,其中数组中的每个元素表示该节点指向的节点的索引。因此,这是我尝试过的代码(不完全是dfs,但仍然):

int-leastcommon子代(int-nodes[],int-N,int-node1,int-node2)
{
int*visted=新int[N];
int cnt1=0;//用于计算从节点1到节点2的路径长度
int cnt2=0;//用于计算从节点2到节点1的路径长度
int mark=node1;//存储为以后检测搜索结束所需的标记
if(node1==node2)返回node2;
对于(int i=0;i
通常,它可以在
O(h)
中完成,方法是逐步“向上”树(在原始图形中向前),并将找到的节点存储在一个集合中,直到集合交集不为空


如果允许预处理,可以在线性时间内对其进行预处理以获得更好的重定值。

有效吗?如果无效,为什么以及在哪里无效?在O(logN)中不可能做到这一点时间请提供您的问题的链接。@Phamtrong不幸的是,没有链接,这是一个面试问题。我尽可能多地叙述,请查看编辑。如果这个图有一个循环会怎么样?@sky_coder123 DAG是有向无环图,它怎么会有一个循环?哦,很抱歉。实际上,我无法制定它在我开始解决这个问题的规定时间内,因为问题是用竞争编码的话来说的。我已经更改了标记以反映相同的情况。@Phamtrong甚至DAG也可以有循环,只是它没有定向循环。
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;
}