Kosaraju
这是个用来求连通分量的算法
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4psPXfsS-1656821811763)(C:\Users\YYYYYKN\AppData\Roaming\Typora\typora-user-images\image-20220611210325166.png)]](https://img-blog.csdnimg.cn/459c1387004c47b59bc3bf743076bad5.png)
使用两次dfs,第一次dfs在原图中进行遍历,可以确定dfs后序序列,从尾到头遍历就是dfs逆后序序列。第二次dfs按照逆后序序列在反图中进行遍历,这个时候能用dfs遍历到的就是强连通分量了。
int n;
int vis[100000000] = {0};
vector<vector<int>> yuantu,fantu;
int liantongfenliang[100000000];
int liantongxuhao = 0;
int houxu[10000000] = {0};
int dfsn1 = 0;
void dfs1(int x)
{
vis[x] = 1;
for(int i = 0;i < yuantu[x].size();i ++)
if(vis[yuantu[x][i]] == 0)
dfs1(yuantu[x][i]);
houxu[dfsn1 ++] = x;
}
void dfs2(int x)
{
liantongfenliang[x] = liantongxuhao;
for(int i = 0;i < fantu[x].size();i ++)
if(liantongfenliang[fantu[x][i]] == -1)
dfs1(fantu[x][i]);
}
void kosaraju()
{
for(int i = 1;i<=n;i ++)
liantongxuhao = -1;
for(int i = 1;i <= n;i ++)
{
if(vis[i] == 0)
dfs1(i);
}
for(int i = n;i >= 1;i --)
{
if(liantongfenliang[houxu[i]] == -1)
{
liantongxuhao ++;
dfs2(houxu[i]);
}
}
}
接下来可以利用原图的点的那些边和那些点现在所属的连通分量来缩点,构建一个有向无环图
缩点后的去除重复边操作
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ff8XdLio-1656821811766)(C:\Users\YYYYYKN\AppData\Roaming\Typora\typora-user-images\image-20220502212122117.png)]](https://img-blog.csdnimg.cn/9b9e562c03ff45f59845e7eef335f533.png)
STL中unique的函数的功能,是去除相邻的重复元素(只保留一个),把重复的放到序列后面,返回的是不重复序列的最后一个数
这里复习一下vector的erase()
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V38obg1w-1656821811769)(C:\Users\YYYYYKN\AppData\Roaming\Typora\typora-user-images\image-20220502212405759.png)]](https://img-blog.csdnimg.cn/228446d119fc49acb9e2c3dac98930ed.png)