题目链接:https://vjudge.net/problem/POJ-1144
题意:给出N个点,然后下面若干行,某一行第一个数位u,之后若干个数为v,表示u,v有一条双向边。注意下输入。
题解:裸的Tarjan算法求割点数目。
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <stdlib.h>
#include <set>
using namespace std;
const int N = 107;
int low[N];
int dfn[N];
vector<int>G[N];
set<int>S;
int index;
int root;
void Tarjan(int u, int fa)
{
dfn[u] = low[u] = ++ index;
int n = G[u].size();
int son = 0;
for(int i = 0;i < n;i ++) {
int v = G[u][i];
if(v == fa) continue;
if(!dfn[v]) {
son ++;
Tarjan(v, u);
low[u] = min(low[u], low[v]);
if(root == u && son > 1 || root != u && low[v] >= dfn[u]) S.insert(u);
} else {
low[u] = min(low[u], dfn[v]);
}
}
}
int main()
{
int n;
while(scanf("%d", &n) && n) {
int u;
S.clear();
for(int i = 1;i <= n;i ++) {
dfn[i] = low[i] = 0;
G[i].clear();
}
while(scanf("%d",&u) && u) {
while((getchar()) != '\n') {
int v;
scanf("%d",&v);
G[u].push_back(v);
G[v].push_back(u);
}
}
for(int i = 1;i <= n;i ++) {
if(!dfn[i]) {
index = 0;
root = i;
Tarjan(i, -1);
}
}
printf("%d\n", (int)S.size());
}
return 0;
}