问题
如果我们用邻接矩阵来存储图,那么绝大多数图算法的运行时间都是Ω(|V|2)(V为一个图的顶点集),但还是有些例外。比如,给定一个有向图G的邻接矩阵A,我们可以在Ο(|V|)时间内判断图G是否包含一个通用汇点,即一个入度为|V|-1出度为0的顶点。请给出这样的算法。
思路
(注:这一段是我从教师手册翻译过来的,和我的思路一样,不过表述和逻辑更清晰。)如果A[i, j] = 1,即(i, j)∈E(1≤i≤|V|,1≤j≤|V|,E是G的边集),那么顶点i就不可能是通用汇点,因为它有一条出边。因此,如果第i行有一个元素为1,那么顶点i就不可能是通用汇点。这也意味着如果i有一条自循环边,那么它就不可能是通用汇点。现在假设A[i, j] = 0,即(i, j)∉E,且i≠j。在这种情况下,顶点j就不可能是通用汇点,因为要么它的入度严格小于|V|-1,要么它包含一个自循环边。因此,如果第j列有一个非对角线上的元素为0,那么顶点j就不可能是通用汇点。
因此,这个问题等价于:给定一个有向图G的|V|×|V|邻接矩阵A,在O(|V|)时间内判断是否存在一个整数j(1≤j≤|V|),使得对于所有的i(1≤i≤|V|且i≠j)都有A[i, j] = 1,对于所有的k(1≤k≤|V|)都有A[j, k] = 0。更形象地说,就是判断A里面是否有这样一个“十”字:这“十”字的横全是0,竖全是1(除了“十”字的中心)。
我的解法
(注:下面用aij表示A[i, j],用左箭头←表示赋值操作。)