这是一个求割点的题目 ,
要注意两点:
1、所有点不一定是连续的
2、每组数据要输出一个换行
求分成几个连通分量 , 就等于是割点有几颗子树(子树中回边的lowv 比 割点的 low[u]大)+ 1 , 但是根结点例外 , 不需要+1;
代码:
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXN = 1010 ;
vectorgrap[MAXN*2] ;
int pre[MAXN] , low[MAXN] , iscnt[MAXN] ;
int dfs_clock , n = 0;
void init()
{
for(int i =
1 ; i <= n ; i++)
grap[i].clear();
memset(pre,
0 , sizeof(pre));
memset(iscnt
, 0 , sizeof(iscnt));
dfs_clock =
0;
}
int dfs(int u , int fa)
{
int lowu =
pre[u] = ++dfs_clock;
int child =
0;
for(int i =
0 ; i < grap[u].size() ; i++)
{
int v =
grap[u][i];
if(!pre[v])
{
child++;
int lowv =
dfs(v , u);
if(lowv
< lowu) lowu = lowv;
if(lowv
>= pre[u])
iscnt[u] +=
1;
}
else
if(pre[v] < pre[u]
&& v != fa)
{
if(pre[v]
< lowu) lowu = pre[v];
}
}
if(fa
< 0) iscnt[u] -= 1;
low[u] =
lowu;
return
lowu;
}
int main()
{
int xy =
1;
while(1)
{
init();
int i , x ,
y;
n = 0;
int
gh[MAXN];
memset(gh ,
0 , sizeof(gh));
for(i = 0; ;
i++)
{
scanf("%d" ,
&x);
if(x == 0
&& i ==0) return
0;
else if(x ==
0) break;
scanf("%d" ,
&y);
grap[x].push_back(y);
grap[y].push_back(x);
if(x
> n) n = x;
if(y
> n) n = y;
gh[x] =
gh[y] = 1;
}
for(i = 1; i
<= n; i++)
if(!pre[i]
&& gh[i])
{
dfs(i ,
-1);
}
bool bz =
false;
printf("Network #%d\n" , xy++);
for(i = 1; i
<= n; i++)
{
if(iscnt[i])
{
printf(" SPF node %d leaves %d subnets\n" , i ,
iscnt[i]+1);
bz =
true;
}
}
if(!bz) printf(" No SPF
nodes\n");
cout<<endl;
}
return
0;
}
要注意两点:
1、所有点不一定是连续的
2、每组数据要输出一个换行
求分成几个连通分量 , 就等于是割点有几颗子树(子树中回边的lowv 比 割点的 low[u]大)+ 1 , 但是根结点例外 , 不需要+1;
代码:
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXN = 1010 ;
vectorgrap[MAXN*2] ;
int pre[MAXN] , low[MAXN] , iscnt[MAXN] ;
int dfs_clock , n = 0;
void init()
{
}
int dfs(int u , int fa)
{
}
int main()
{
}