题意:求一个无向图的割顶(点)。
题目链接:http://poj.org/problem?id=1144
——>>low[i]为i和i的后代能连到dfs中层次最浅的结点,对于一个结点u,如果u不是根且low[u] >= pre[u],或者u是根且u的”孩子“(与根相连的点数减去其反向边数)不只1个,则u是割顶(点)。
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>using namespace std;const int maxn = 100 + 10;
int pre[maxn], low[maxn], N, dfs_clock;
bool iscut[maxn];
vector<int> G[maxn];void init()
{dfs_clock = 0;memset(pre, 0, sizeof(pre));memset(iscut, 0, sizeof(iscut));
}int dfs(int u, int fa)
{int lowu = pre[u] = ++dfs_clock, child = 0;int cnt = G[u].size();for(int i = 0; i < cnt; i++){int v = G[u][i];if(!pre[v]){child++;int lowv = dfs(v, u);lowu = min(lowu, lowv);if((u == 1 && child > 1) || (u != 1 && pre[u] <= low[v])) iscut[u] = 1;}else if(pre[v] < pre[u] && v != fa) lowu = min(lowu, pre[v]);}return low[u] = lowu;
}int main()
{int u, v, i;while(scanf("%d", &N) == 1 && N){for(i = 1; i <= N; i++) G[i].clear();while(scanf("%d", &u) == 1 && u){while(getchar() != '\n'){scanf("%d", &v);G[u].push_back(v);G[v].push_back(u);}}init();dfs(1, -1);int cnt = 0;for(i = 1; i <= N; i++) if(iscut[i]) cnt++;printf("%d\n", cnt);}return 0;
}