在图论中,连通图基于连通的概念。在一个无向图G中,若从顶点到顶点有路径相连(当然从到也一定有路径),则称和是连通的。如果G是有向图,那么连接和的路径中所有的边都必须同向。如果图中任意两点都是连通的,那么图被称作连通图。图的连通性是图的基本性质。
将有向图的所有的有向边替换为无向边,所得到的图称为原图的基图。如果一个有向图的基图是连通图,则有向图是弱连通图,弱有向图的任意两点都可以相互到达那么称这个有向图为强连通图,如果一个有向图的子图是强连通图,那么这个子图称为该有向图的强连通分量。有向图中一个单个的点也是一个强连通分量
Tarjan在无向图里可以求割点和割桥。在有向图里可以求强连通分量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
|
1.HDU1269
裸Tarjan求强连通分量个数,跑N遍Tarjan得到的NUM就是结果
2.POJ2186
Tarjan后重建图判断出度为0的节点个数,若为1则OK。
for
(
int
i=
1
;i<=n;i++)
{
for
(
int
j=
0
;j<Gra[i].size();j++){
int
k = Gra[i][j];
if
(belong[i] != belong[k]){
outDegree[belong[i]]++;
}
}
}
其实也算不上重建图....只是求了一下各个节点的出度而已......
3.POJ2762
Tarjan + 拓扑排序
这个题是真的烦人,都给我WA哭了有木有,从中午2点错到晚上10点,中间气的我玩了几把游戏,真的气。
还有一个就是有人说缩晚点以后的DAG是一条链,也有好多人是这么写的,都AC了,说是dfs点的数目等于强连通块的数目就可以。
但是感觉明显不对啊,整个就是一个树,你dfs的点数肯定等于
强连通块的数目啊,不懂他们怎么A的。
感觉和2186差不多,但是最多只有1000个顶点。
我怎么这么愚蠢,居然想到要暴力!!!我太蠢啦!!!
学长一语点醒
我这都没想到-。-||
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
|
4.HYSBZ 1179
这个就是tarjan + bfs就可以了,我感觉我的代码命名都很清晰,一看就明白了。
还有就是网上好多人都是 tarjan + spfa,但我感觉spfa没有必要,因为缩点以后的图一定是一个DAG图。他的搜索树一定是一个没有向后边的的树,所以一遍vfs 就够了。
5.最后说一下就是,这个缩点的时候,如果只用入度出度是否为0就能得到答案的话直接
for
(
int
i=
1
;i<=n;i++)
{
for
(
int
j=
0
;j<Gra[i].size();j++){
int
k = Gra[i][j];
if
(belong[i] != belong[k]){
outDegree[belong[i]]++;//inDegree[belong[i]]++;
}
}
}
就可以了。
但是假如要对入度出度进行操作就不可以了,因为强连通块1是由1,2,3节点构成,强连通块2是由4,5构成
现在缩点后块1 ----> 块2。其中节点2 ---> 4,
2 ---> 5,3 ---> 5。这样下来outdegree[1] == 3;
indegree[2] == 3;这其实就错了,如果拓扑排序是不出结果的。比如上面的poj2762.
那么这个类型的就告一段落了,感觉掌握的还不错,因为本身Tarjan比较好理解(当然一开始看的时候各种网上找讲解
也是看得我一脸懵逼,一开始看还是有点不好想的)但是只要理解了以后代码,就很好打了。