Problem:
给定一个连通图,求割点的数目。
Solution:
利用tarjan模板求出割点数组,输入有些麻烦。
#include<cstdio>
#include<iostream>
#include<sstream>
#include<cstdlib>
#include<cmath>
#include<cctype>
#include<string>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<ctime>
#include<vector>
#include<fstream>
#include<list>
using namespace std;
const int maxn = 110;
int times;
int dfn[maxn], low[maxn];
bool cut[maxn];
vector<int> G[maxn];
void Tarjan(int u, int fa){
dfn[u] = low[u] = ++times;
int childs = 0;
for(int i = 0; i < G[u].size(); ++i){
int v = G[u][i];
if(!dfn[v]){
childs++;
Tarjan(v, u);
low[u] = min(low[u], low[v]);
if(low[v]>=dfn[u] && fa>0)//割点
cut[u] = true;
// if(low[v] > dfn[u])
//u-v是一个桥,但需要判断是否有重边
}
else if(fa != v)//因为这是一个无向图
low[u]=min(low[u], dfn[v]);
}
if(fa < 0)
cut[u] = (childs>=2) ? true : false;
}
int main(){
// freopen("E:\\input.txt","r",stdin);
int n;
while(~scanf("%d",&n) && n){
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(cut,0,sizeof(cut));
times = 0;
int u,v;
for(int i = 1; i <= n; ++i)
G[i].clear();
while(scanf("%d",&u) && u){
while(getchar()!='\n'){
scanf("%d",&v);
G[u].push_back(v);
G[v].push_back(u);
}
}
Tarjan(1,-1);
int ans = 0;
for(int i = 1; i <= n; ++i)
if(cut[i])
ans++;
printf("%d\n",ans);
}
return 0;
}