无向连通图的割点,即为除去该点,不再连通。
求割点数量, 参考代码(待续):
#include<stdio.h>
#define MAX_LEN 100
int network[MAX_LEN + 2][MAX_LEN + 2];
int low[MAX_LEN+2];
int dnf[MAX_LEN+2];
bool visited[MAX_LEN+2];
int tmpDnf;
int critcalCnt;
int N;
int son;
int subNet[MAX_LEN+2];
void init(){
int i, j;
critcalCnt = 0;
tmpDnf = 1;
son = 0;
for (i = 1; i <= MAX_LEN; i++) {
low[i] = dnf[i] = subNet[i] = 0;
visited[i] = false;
for(j = 1; j <= MAX_LEN; j++) {
network[i][j] = 0;
}
}
}
int getMin(int num1, int num2) {
return num1 > num2 ? num2: num1;
}
void dfs(int u) {
int v;
for(v = 1; v <= N; v++) {
if(network[u][v] == 1) {
if(visited[v] == false) {
tmpDnf++;
low[v] = dnf[v] = tmpDnf;
visited[v] = true;
dfs(v);
low[u] = getMin(low[u], low[v]);
if(low[v] >= dnf[u]) {
if(u == 1){
son++; // 根节点需要至少两个子女
} else {
subNet[u]++;
}
}
} else {
low[u] = getMin(low[u], dnf[v]);
}
}
}
}
void countCritical(){
int i;
for(i = 1; i <=N; i++) {
if(subNet[i] > 0) // 分成子网络个数 为 subNet[i] +1 ,包括它的祖先
critcalCnt++;
}
}
int main(){
int a, b, c;
//freopen("input.txt", "r", stdin);
while(scanf("%d",&N),N){
init();
while(scanf("%d",&a),a){
while(1){
c = getchar();
if(c == '\n')break;
scanf("%d",&b);
network[a][b] = 1;
network[b][a] = 1;
}
}
low[1] = dnf[1] = 1;
visited[1] = true;
dfs(1);
if(son > 1) // 根节点需要至少两个子女
subNet[1] = son -1;
countCritical();
printf("%d\n", critcalCnt);
}
return 0;
}
参考链接:
http://blog.youkuaiyun.com/yangkunpengd/article/details/51298144
https://www.cnblogs.com/llhthinker/p/4954082.html#autoid-0-0-0