边双连通分量:若一个无向图中的去掉任意一条边都不会改变此图的连通性,即不存在桥,则称作边双连通图。
一个无向图中的每一个极大边双连通子图称作此无向图的边双连通分量。
连接两个边双连通分量的边即是桥(bridge)
点双连通分量:若一个无向图中的去掉任意一个节点都不会改变此图的连通性,即不存在割点,则称作点双连通图。
一个无向图中的每一个极大点双连通子图称作此无向图的点双连通分量。
连接两个边双连通分量的点即是关节点(articulation)
算法:
int bicompDFS(v)
color[v]=gray; pre[v]=clock; clock++;
back = pre[v];
while( there is an untraversededge vw)
push vw into edgeStack
if (vwis a tree edge)
wBack= bicompDFS(w);
if(wBack>=pre[v])
Output a new bicomponent
by popping edgeStackdown through vw;
back=min( back, wBack);
else if(vwis a back edge)
back=min( pre[w], back );
post[v]=clock; clock++;color[v]=black;
return back;
代码:
/*测试数据
10 14
0 3
0 5
0 7
5 7
5 9
3 5
3 9
4 5
1 4
2 4
1 2
1 6
1 8
6 8
*/
#include "pch.h"
#include <iostream>
#include<list>
#include<stack>
#include<algorithm>
#include<set>
using namespace std;
const int MAX = 100;
enum color{white,gray,black};
struct edge//边结构,储存边的两个结点
{
int u;
int v;
};
class Graph
{
int n;//顶点数
int m;//边数
int **AdjMatrix;
color c[MAX];
int pre[MAX];
int post[MAX];
int back[MAX];
int clock = 1;//timestamp
stack<edge> edgeStack;
public:
Graph(int n, int m);
~Graph();
int bicompDFS(int v);
};
Graph::Graph(int n, int m)
{
this->n = n;
this->m = m;
int u, v;
AdjMatrix = new int*[n];//分配内存
for (int i = 0; i < n; i++)
AdjMatrix[i] = new int[n];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
AdjMatrix[i][j] = 0;
for (int i = 0; i < m; i++)//初始化
{
cin >> u >> v;
AdjMatrix[u][v] = 1;
AdjMatrix[v][u] = 1;
}
for (int i = 0; i < n; i++)
{
c[i] = white;
pre[i] = 0;
back[i] = 0;
}
}
Graph::~Graph()
{
delete[]AdjMatrix;
}
int Graph::bicompDFS(int v)
{
c[v] = gray; pre[v] = clock; clock++;
back[v] = pre[v];
for (int i = 0; i < n; i++)
{
if (AdjMatrix[v][i]==1)//v到i有边
{
AdjMatrix[v][i] = 2;
AdjMatrix[i][v] = 2;
edge e;
e.u = v; e.v = i;
edgeStack.push(e);
if (c[i]==white)//判断树边,或者可以将条件设置为pre[i]==0
{
back[i] = bicompDFS(i);
if (back[i] >= pre[v])
{
cout << "双连通分量:";
set<int>s;
while (1)
{
edge e = edgeStack.top();
edgeStack.pop();
s.insert(e.v); s.insert(e.u);
if (e.u == v)
break;
}
for (set<int>::iterator it = s.begin(); it != s.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
back[v] = min(back[v], back[i]);
}
else
back[v] = min(pre[i], back[v]);
}
}
post[v] = clock; clock++; c[v] = black;
return back[v];
}
int main()
{
int n, m;
cin >> n >> m;
Graph g(n, m);
g.bicompDFS(0);
}