You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

图论技术题:选择有向图Sink顶点判定算法的E3表达式

判断有向图Sink顶点算法中E3的正确表达式分析

咱们先把基础概念掰明白:Sink顶点i得同时满足两个硬条件:

  • 对所有跟i不一样的顶点j,都有一条从j到i的边(反映在邻接矩阵里就是 A[j][i] = 1
  • 从i出发,连一条到其他顶点的边都没有(对应邻接矩阵里 A[i][j] = 0,所有j≠i都得满足)

再看题目里的算法:前面的do-while循环其实是在快速筛选出一个可能是Sink的候选顶点i,后面的for循环才是关键——要验证这个候选i到底是不是真的符合Sink的定义,只要发现任何不符合的情况,就把flag置为0,判定不存在Sink。

现在聚焦到for循环里的判断:if ((j != i) && E3) flag = 0;,这句话的意思是:当j不是i的时候,如果E3成立,就说明这个i绝对不是Sink,直接标记失败。那我们反过来想,E3应该对应“违反Sink定义的情况”,只要出现这种情况,就排除i是Sink的可能。

那违反Sink定义的情况是什么呢?就是不满足前面说的两个条件里的任意一个:
要么是A[i][j] = 1(i居然有出边到j,违反了第二个条件),要么是A[j][i] = 0(j没有边到i,违反了第一个条件)。把这个逻辑转换成表达式就是:A[i][j] || !A[j][i],也就是选项D。

再顺便说说其他选项为什么不对:

  • 选项A:(A[i][j] && !A[j][i]):这个要求同时满足i有出边、j没有入边才触发,但其实只要其中一个情况出现,i就不是Sink了,这个条件太苛刻,会漏掉很多不符合的情况。
  • 选项B:(!A[i][j] && A[j][i]):这其实是完全符合Sink的情况啊!要是用这个,会把正确的候选当成错误,逻辑完全搞反了。
  • 选项C:(!A[i][j] || A[j][i]):同样是符合Sink定义的情况,用它的话会误判正确的候选,逻辑反了。

所以正确答案就是选项D。

内容的提问来源于stack exchange,提问作者Geeklovenerds

火山引擎 最新活动