题意:求一个无向图的割顶(点)。
题目链接: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;
}