在一个无向图中,若删除某一个节点,使得图分成若干个不相联通的子图,那么,这个节点就是图的割点。就像下图所示:
节点1、节点3和节点4,都是这个图的割点。为什么呢?你想啊,把节点1、节点3和节点4遮住,会怎么样?节点2永远也没法去到6 5 8 7 那些,同理,遮住节点4后,7,8也没法去到6 5 了。这样,就形成了一个个独立子图了。
那么,我们怎么知道这个点,就是割点呢?
①、用两个DFS,删除某个节点后,对其后面的节点进行DFS,如果在【不同过该节点】的情况下,不能回到以前的节点,那么,被删除的节点就是割点啦。删除?怎么删除,其实只需一个book数组,book[i]=1;DFS后,book[i]=0;就OK 啦。。起到一个临时标记,也就起到了"删除"的效果了。最后,book[i]=0;是要把删除的节点补回来。我们没理由弄破一个图吧?  ̄□ ̄|| 最后,该算法的复杂度是O(N(N+M)); 怎样?很复杂吧?有没有其他优秀的算法呢?
②、只需一个DFS,不过要增加两个数组:
一个是num[];//记录的是这个顶点在遍历时,是第几个被访问到的
一个是low[];//表示一个节点,在不经过其父亲时,能回到最早的祖先是谁
::>_<:: 。。什么是父亲?祖先又是谁?这里我们把问题抽象化一下,在上图中,假设我们从1号顶点开始DFS,那么,1顶点能直接去到的顶点,我们称其为1号顶点的儿子,那么,一号顶点就是其父亲。这里需要记住一点:【父亲的num[i]】总是比儿子的少,因为辈分越大,数值越小,我们可以理解为,我爷爷是第一代传人,爸爸是第二代,我是第三代。记住这点很重要哦⊙▂⊙。
那么,假如一个顶点cur,在不经过其父亲顶点father的时候,总能回到更早的顶点(father的祖先),那么,这个father就不是割点。就比如图中的5号顶点,(根据上面,此时的father=5,cur=4),如果删除了5号顶点,cur还是能够通过6号顶点回到3顶点,甚至能回到1号顶点,此时,cur就能回到father的祖先了,此时,father=5并不是图的割点。
相反,如果一个顶点cur,在不经过其父亲顶点father的时候,总不能回到更早的顶点(father的祖先),那么,这个father就是割点啦!比如图中的4号顶点。
那么,我们怎么判断它不能回到自己【父亲的祖先呢】?其实只需要low[cur]>=num[father];就是,儿子能回到最早的祖先,最多最多,也只是它的爸爸。也就是,我不问过我爸爸,我连我爷爷是谁都不知道,那么,爸爸起到连通我和我爷爷的作用,所以,我爸爸就是割点了。 ̄□ ̄||。 我们再来形象理解下这句代码low[cur]>=num[father];我们用辈分来论事,记得我上面说过一句话很重要的吗?拉上去看看吧。这里,我先说个小故事。
话说,在古代,风家人才辈出,能才能武,祖祖祖祖祖祖祖祖爷也还在世上。 ̄□ ̄||。要知道,在这些高人辈出的家族里,有些长辈不是你想见就能见的,有些族人一生在世,没见过爷爷一面也有可能,因为高手一般都是闭关的。。但是如果经过父亲的推荐,那就不同了。一般儿子是绝对知道自己的父亲的,这点不用我说了吧。 ̄□ ̄||。所以cur的father就向他的父亲(就是cur的爷爷)说:我儿子cur天生神力,资质颇高,父亲你就点拔他一些武功吧,爷爷说,"哦,好好好,报名费5000大洋!"这样,cur就能知道他爷爷是谁了。但是,如果cur的父亲father不是伯乐,不知道cur是千里马,那就麻烦了,cur会被埋没的。就这样,cur一辈子平平淡淡,真是伤仲永哇,cur的父亲father,成了cur的"割点"了,就是,cur在不经过他爸爸father的推荐下,不能知道他的爷爷,爷爷爷,爷爷爷爷是谁,那么此时,cur只认识他的爸爸。说来说去,你还没告诉我low[cur]>=numer[father]是什么嘛!我该怎么判断cur是否只认识他爸爸呢?(请把这两句话看3遍)。没错,你想到了,low[cur]>=number[father];就是表明cur最多只认识他的爸爸。low[cur]==number[father]的时候,就表明cur知道自己的爸爸。为什么是?>=而不是<=呢?我们看看辈分?爷爷是第一辈,爸爸是第二辈,我是第三辈。如果我知道我爷爷是谁,low[cur]=1了,而number[father]=2;此时,low[cur]<number[father]。也就说明我能去到爷爷,father不是割点。
number[]//其实number代表的是自己的辈分,
low[];//代表我能认识到最老的长辈。注意,越老,值越小。因为辈分是1
说了那么多,我们来看看完整的代码?
对了,我还没说过child和root的事情,root代表的是祖爷(第一代传人,就是家主)。因为家主没可能成为其儿子的割点啊,家主都没父亲(他从石头爆出来的),那么1为什么还是割点啊,这里他是妨碍了自己的儿子见面,他的儿子也是的,师兄都不见面,各立一派吗?哦,对哦,家主之位,岂能乱传?所以,一般古代那些皇帝的儿子,都是闹不和的,为什么?大家都想自己的爸爸给皇帝位给我啊。!!!
child代表的是儿子,要注意,这里的child==2不代表家主只有一个儿子,代表的是,家主闹不和的儿子达到了两个,家主就是割点了。。最后,希望我们能动笔把每次dfs都写出来,这样,理解起来,更加的好、、
本人初出茅庐,有什么不正确的地方,希望朋友们能指教下,我感激不尽。。共同努力