题目链接: http://poj.org/problem?id=1144
思路分析:该问题要求求出无向联通图中的割点数目,使用Tarjan算法即可求出无向联通图中的所有的割点,算法复杂度为O(|V| + |E|);
代码如下:
#include <cstdio> #include <vector> #include <cstring> #include <iostream> using namespace std; const int MAX_N = 100 + 10; const int MAX_M = 200 + 20; char str[MAX_M]; vector<int> G[MAX_N]; int pre[MAX_N], is_cut[MAX_N], low[MAX_N]; int dfs_clock; inline int Min(int a, int b) { return a < b ? a : b; } int Dfs(int u, int fa) { int lowu = pre[u] = ++dfs_clock; int child = 0; for (int i = 0; i < G[u].size(); ++i) { int v = G[u][i]; if (!pre[v]) { child++; int lowv = Dfs(v, u); lowu = Min(lowu, lowv); if (lowv >= pre[u]) is_cut[u] = true; } else if (pre[v] < pre[u] && v != fa) lowu = Min(lowu, pre[v]); } if (fa < 0 && child == 1) is_cut[u] = 0; low[u] = lowu; return lowu; } int main() { int ver_num; while (scanf("%d", &ver_num) != EOF && ver_num) { getchar( ); int ver_start, ver_next; memset(pre, 0, sizeof(pre)); memset(low, 0, sizeof(low)); memset(is_cut, 0, sizeof(is_cut)); for (int i = 0; i < MAX_N; ++i) G[i].clear( ); while (scanf("%d", &ver_start) && ver_start) { while (getchar() != '\n') { scanf("%d", &ver_next); G[ver_start].push_back(ver_next); G[ver_next].push_back(ver_start); } } int cut_ver_count = 0; dfs_clock = 0; Dfs(1, -1); for (int i = 1; i <= ver_num; ++i) { if (is_cut[i]) cut_ver_count++; } printf("%d\n", cut_ver_count); } return 0; }