题意:求割点,并计算去掉割点后连通分支的数量。
#include <iostream>
using namespace std;
#define N 1005
#define min(a,b) (a<b?a:b)
int size, id;
int head[N], vis[N];
int low[N], dfn[N], connect[N];
struct { int v, next; } edge[N];
void add ( int u, int v )
{
size++;
edge[size].v = v;
edge[size].next = head[u];
head[u] = size;
size++;
edge[size].v = u;
edge[size].next = head[v];
head[v] = size;
}
void dfs ( int u )
{
vis[u] = true;
low[u] = dfn[u] = ++id;
for ( int i = head[u]; i; i = edge[i].next )
{
int v = edge[i].v;
if ( vis[v] )
low[u] = min ( low[u], dfn[v] );
else
{
dfs ( v );
low[u] = min ( low[u], low[v] );
if ( low[v] >= dfn[u] ) connect[u]++;
}
}
}
int main()
{
int u, v, flag, i, cs = 0;
while ( scanf("%d",&u) && u )
{
size = id = 0;
memset(head,0,sizeof(head));
scanf("%d",&v);
add ( u, v );
while ( scanf("%d",&u) && u )
{
scanf("%d",&v);
add ( u, v );
}
for ( i = 1; i <= 1000; i++ )
vis[i] = low[i] = dfn[i] = connect[i] = 0;
dfs ( 1 );
connect[1]--;
printf("Network #%d\n",++cs);
for ( i = 1, flag = 0; i <= 1000; i++ )
{
if ( connect[i] <= 0 ) continue;
flag = 1;
printf(" SPF node %d leaves %d subnets\n", i, connect[i]+1 );
}
if ( flag == 0 )
printf(" No SPF nodes\n");
putchar('\n');
}
return 0;
}