使用O(N)中的邻接矩阵在有序图中查找根顶点

时间:2013-06-19 16:11:22

标签: matrix graph-algorithm

我有一个ordered graph的邻接矩阵,我需要找到所有其他边缘到的顶点(在它的行中除了对角线之外都有1个):

如果这是邻接矩阵:

0 0 0
0 0 0
1 1 0

算法应该产生顶点3。

假设至少有一个这样的顶点。

O(N ^ 2)中的解(N是顶点数)是微不足道的,但如何在O(N)中完成?

2 个答案:

答案 0 :(得分:2)

前提条件:

  • 图表为ordered graph
  • 有一个顶点,所有其他顶点都有一个边缘到

由于边缘需要引入总排序,所以需要找到的顶点是“最小”顶点,它没有任何外边缘,因为这将是它已连接的其他边之一to会导致一个循环,这在一个有序图中是不允许的。

此外,图形需要连接,因此所有路径都需要通向最小的顶点,这使我们得到了这个算法:

  1. 从所有行的集合开始作为可能的候选人
  2. 从集合中选择一个顶点,并将可能的边缘迭代到剩余的候选者。
    • 如果候选人有优势,请从列表中删除第2步中的候选人,并在新候选人的2位继续。
    • 如果该顶点没有边缘,则从候选集中移除目标候选者并继续下一个可能的边缘。
    • 如果没有留下候选人,则当前顶点是您要查找的顶点
  3. 由于每个步骤都可以在O(1)中执行,并且在每个步骤中减少剩余候选者的集合,因此运行时间应该是O(N)。

答案 1 :(得分:0)

有序图是在其顶点上具有总次序的图。没有其他要求,特别是它不限制边缘可以去的地方。所以这个问题的答案是你有时候不能做得比O(N ^ 2)更好:考虑一个邻接矩阵,其中一行所有非对角线条目等于一,而所有其他行都有一个零非对角线条目。除非你非常幸运,否则你需要通过几乎整个邻接矩阵找出哪一行没有非对角线零。

因此,我认为您的意思是指向允许 topological ordering 的有向图。也就是说,directed acyclic graph(DAG)。在那种情况下,塞巴斯蒂安已经回答了,但由于答案未被接受,让我试着更清楚地解释它。

如果DAG中的顶点具有来自每个其他顶点的入射边,则它没有外出边,因为它们将形成长度为2的循环。换句话说,其对应列仅具有零。这样的顶点称为通用接收器,并且有一种众所周知的O(N)算法可用于查找它。

常规算法:

  1. 候选人:= {0,1,...,N-1}
  2. 而|候选人| > 1做:
    • 任意选择候选人u和v
    • if(u,v)是边缘,从cadidates中删除u,否则从候选人中删除v
  3. 测试最后剩余的候选人是否为通用接收器
  4. 如果你知道你的图表有一个通用接收器,那么最后一步是不必要的。

    while循环的迭代次数为N-1,因为每次迭代都会从候选集中删除一个顶点。该算法是正确的,因为它只删除不能成为通用接收器的顶点 - 移除的顶点具有传出边缘,或者它没有来自某个顶点的传入边缘。

    在下面的代码中,您可以注意到我们没有明确地保留候选人列表。 for-cycle的步骤 i 中的候选者列表是 {candidate,i,i + 1,...,N-1} 和所选候选人 u v 候选人 i

    // step 2
    int candidate = 0;
    for(int i=1; i<N; i++)
    {
      if(edge[candidate][i] == 1)
          candidate = i;
    }
    // step 3
    bool no_sink = false;
    for(int i=0; i<N; i++)
    {
      if(candidate  != i && (edge[candidate][i] == 1 || edge[i][candidate]==0))
          no_sink = true; 
    }
    if(no_sink)
        printf("No universal sink.");
    else
        printf("The universal sink is %d.", candidate);