题意:给一个无向连通图,求出割点的数量。
首先输入一个N(多实例,0结束),下面有不超过N行的数,每行的第一个数字代表后面的都和它存在边,0表示行输入的结束(很蛋疼的输入方式).
分析:割点的模板题
******************************************************************
#include<stdio.h>
#include< string.h>
#include<stack>
#include<algorithm>
using namespace std;
const int MAXN = 105;
struct Edge{ int v, next;}e[MAXN*MAXN];
int Head[MAXN], cnt;
void AddEgde( int u, int v)
{
e[cnt].v = v;
e[cnt].next = Head[u];
Head[u] = cnt++;
}
int f[MAXN], nRootSons; /// 记录父亲节点,和根节点的子树个数
int blsCutVetext[MAXN]; /// 是否属于割点
int Low[MAXN], Dfn[MAXN], Index; /// low保存深搜最早能够到达的点
void InIt( int N) /// 初始化
{
cnt = nRootSons = Index = 0;
for( int i= 0; i<=N; i++)
{
Head[i] = - 1;
blsCutVetext[i] = false;
Dfn[i] = false;
}
}
void Tarjan( int u, int father)
{
f[u] = father;
Low[u] = Dfn[u] = ++Index;
for( int j=Head[u]; j!=- 1; j=e[j].next)
{
int v = e[j].v;
if( !Dfn[v] )
{
Tarjan(v, u);
Low[u] = min(Low[u], Low[v]);
}
else if( v != father)
Low[u] = min(Low[u], Dfn[v]);
}
}
int main()
{
int N;
while(scanf( " %d ", &N), N)
{
int i, u, v; char End;
InIt(N);
while(scanf( " %d ", &u), u)
{
while( 1)
{
scanf( " %d%c ", &v, &End);
AddEgde(u, v);
AddEgde(v, u);
if(End == ' \n ')
break;
}
}
Tarjan( 1, 0);
for(i= 1; i<=N; i++)
{
u = f[i];
if(u == 1)
nRootSons++;
else if( Dfn[u] <= Low[i] )
blsCutVetext[u] = true;
}
if(nRootSons > 1)
blsCutVetext[ 1] = true;
int ans = 0;
for(i= 1; i<=N; i++)
{
if(blsCutVetext[i] == true)
ans++;
}
printf( " %d\n ", ans);
}
return 0;
#include< string.h>
#include<stack>
#include<algorithm>
using namespace std;
const int MAXN = 105;
struct Edge{ int v, next;}e[MAXN*MAXN];
int Head[MAXN], cnt;
void AddEgde( int u, int v)
{
e[cnt].v = v;
e[cnt].next = Head[u];
Head[u] = cnt++;
}
int f[MAXN], nRootSons; /// 记录父亲节点,和根节点的子树个数
int blsCutVetext[MAXN]; /// 是否属于割点
int Low[MAXN], Dfn[MAXN], Index; /// low保存深搜最早能够到达的点
void InIt( int N) /// 初始化
{
cnt = nRootSons = Index = 0;
for( int i= 0; i<=N; i++)
{
Head[i] = - 1;
blsCutVetext[i] = false;
Dfn[i] = false;
}
}
void Tarjan( int u, int father)
{
f[u] = father;
Low[u] = Dfn[u] = ++Index;
for( int j=Head[u]; j!=- 1; j=e[j].next)
{
int v = e[j].v;
if( !Dfn[v] )
{
Tarjan(v, u);
Low[u] = min(Low[u], Low[v]);
}
else if( v != father)
Low[u] = min(Low[u], Dfn[v]);
}
}
int main()
{
int N;
while(scanf( " %d ", &N), N)
{
int i, u, v; char End;
InIt(N);
while(scanf( " %d ", &u), u)
{
while( 1)
{
scanf( " %d%c ", &v, &End);
AddEgde(u, v);
AddEgde(v, u);
if(End == ' \n ')
break;
}
}
Tarjan( 1, 0);
for(i= 1; i<=N; i++)
{
u = f[i];
if(u == 1)
nRootSons++;
else if( Dfn[u] <= Low[i] )
blsCutVetext[u] = true;
}
if(nRootSons > 1)
blsCutVetext[ 1] = true;
int ans = 0;
for(i= 1; i<=N; i++)
{
if(blsCutVetext[i] == true)
ans++;
}
printf( " %d\n ", ans);
}
return 0;
}