课程主页:

https://cs170.org/

https://inst.eecs.berkeley.edu/~cs170/fa18/

课程视频:

https://www.bilibili.com/video/BV1wK411g7ck

这次回顾Section 2。

1. Cubed Fourier

(a)
(b)

2. Vandermonde Matrices

那么

要使得$MM^T$为对角矩阵,必然有

因为$\alpha_i ,\alpha_j\in \mathbb R$,所以上式必然不可能成立。因此,对于$\alpha_i, \alpha_j\in \mathbb R$,$MM^T$不可能为对角阵,即$M^{-1}\neq c M^T$。

3. Graph Traversal

(a)
(b)

SCC:

  • $A$
  • $B$
  • $E$
  • $C,J,F,D$
  • $H,I,G$
(c)

略。

4. Short Answer

(a)

正确,因为$(u,v)$是前向边。

(b)

错误,反例如下:

(s, u)
(u, s)
(s, v)

DFS的顺序为:$s, u, v$,并且$u$到$v$存在路径,但是$u$不是$v$的祖先。

(c)

正确,删除DFS搜索树的叶节点。

5. True Source

这部分参考了解答。

方法1

对于有向无环图,计算入度为$0$的节点的数量,如果数量$=1$,则返回true,否则返回false。

正确性说明:

如果只有一个入度为$0$的节点,不妨记为$s$,那么从$s$开始DFS,必然能访问全部节点。

利用反证法即可,假设结论不成立,记录$S$为$s$ DFS遍历的节点。

  • 对于任意$v\in V-S$,如果不存在边$(u,v)$,其中$u\in S$,那么由于$G$是有向无环图,$V-S$顶点构成的图也是有向无环图,从而其中存在入度为$0$的点,这就与假设矛盾。
  • 如果存在$v\in V-S$,以及边$(u,v ), u\in S$,这就与$v$无法被遍历相矛盾。

如果有大于一个入度为$0$的节点,不妨记为$s_1, s_2$,从$s_i$开始DFS遍历的节点集合为$S_i$,如果$V-(S_1 \cup S_2)\neq \varnothing$,这说明必然有节点无法访问;否则$S_1\cup S_2 = V$,但是从$S_1$中任意节点开始DFS都无法访问$s_2$,从$S_2$中任意节点开始DFS都无法访问$s_1$,这就说明结论成立。

对于有向有环图,首先计算SCC,然后将强联通部件作为节点,得到的新图必然为有向无环图,运行之前的算法即可。

时间复杂度为

方法2

在原图上运行DFS,搜索树构成森林,记最后一颗搜索树的根节点为$v$,然后以$v$为起点调用DFS,如果能访问全部节点,则返回true,否则返回false。

正确性说明:

只要说明,如果以$v$为起点调用DFS无法访问全部节点,则不存在能访问全部节点的节点。

依然利用反证法,记$u\neq v$为能访问全部节点的节点,那么$u$必然能访问$v$,但是这显然不可能,因为

  • $u$不可能是某棵搜索树的子节点,因为图是有向无环图,存在根节点至$u$的路径说明不存在$u$至根节点的路径。
  • $u$同样不可能是第一轮DFS中某棵搜索树的根节点,因为如果$u$可达$v$,那么$v$必然不是某棵搜索树的根节点,这就与假设矛盾。

综上,结论成立。

6. Path Problems on DAGs

(a)

将$G$中节点拓扑排序得到$v_1,\ldots ,v_n$。

利用动态规划算法:构造数组$dp[n]$,其中$dp[i]$表示以$v_i$为终点的最长路径长度,那么可以得到如下算法:

  • for $i=1,\ldots, n$
    • 如果$v_i$入度为$0$:
      • $dp[i]=0$
    • 否则:
      • $dp[i] =1+\max_{v_j\to v_i\in E} dp[j]$
  • return $\max_{i=1,\ldots,n} dp[i]$
(b)

注意图是有向无环图,所以路径长度小于$n$。

依然使用动态规划算法,构造数组$dp[n][n]$,其中$dp[i][j]$表示,从$s$出发走$j$步到$i$的路径数量,实际上可以只申请一维数组$cnt[n]$,具体算法如下:

  • 构造数组$cnt[n]$,初始化每个元素为$0$
  • $cnt[s]=1$
  • $res = 0$
  • for $i=1,\ldots, n-1$:
    • 构造数组$tmp[n]$,初始化每个元素为$0$
    • for $j=1,\ldots, n$:
      • $tmp[j] = \sum_{v_k \to v_j\in E} cnt[k]$
    • $res= res+tmp[t]$
    • for $j=1,\ldots, n$:
      • $cnt[j]=tmp[j]$
  • return $res$

时间复杂度:

优化方法:

外部的循环可以用拓扑排序来取代。

将$G$中节点拓扑排序得到$v_1,\ldots ,v_n$。

  • 构造数组$cnt[n]$,初始化每个元素为$0$
  • for $i=1,\ldots, n$:
    • 如果$v_i =s$:
      • $cnt[i]= 1$
    • 否则:
      • $cnt[i] =\sum_{v_j\to v_i\in E} cnt[j]$
  • return $cnt[t]$

时间复杂度: