Description

Input
Output
Sample Input
1 2 5 4 3 1 3 2 3 4 3 5 0 1 2 2 3 3 4 4 5 5 1 0 1 2 2 3 3 4 4 6 6 3 2 5 5 1 0 0
Sample Output
Network #1 SPF node 3 leaves 2 subnets Network #2 No SPF nodes Network #3 SPF node 2 leaves 2 subnets SPF node 3 leaves 2 subnets
给出无向边,输入到0结束,问割点是谁,并且求出割点将图分成几个连通分量
割点的求法就是tarjan,在求出割点后用并查集找出将图分成几块,注意对于根,如果根只有一个子树,那么根不是割点,但用tarjan判断也会判断成割点,所以要特判根节点
所以,如果割点找出的分块数是1,不用输出。
输出是坑,要求每个空两个格,一个案例空一行
#include <cstdio>
#include <cstring>
#include <stack>
#include <algorithm>
using namespace std;
#define maxn 1200
struct node
{
int u , v ;
int next ;
} edge[1000000] ;
int head[maxn] , cnt , vis[1000000] ;
int dnf[maxn] , low[maxn] , time ;
int ans[maxn] ;
int c[maxn] , n ;
stack <int> sta;
void init()
{
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
memset(dnf,0,sizeof(dnf));
memset(low,0,sizeof(low));
memset(ans,0,sizeof(ans));
cnt = time = n = 0 ;
}
void add(int u,int v)
{
edge[cnt].u = u ;
edge[cnt].v = v ;
edge[cnt].next = head[u] ;
head[u] = cnt++ ;
edge[cnt].u = v ;
edge[cnt].v = u ;
edge[cnt].next = head[v] ;
head[v] = cnt++ ;
}
int find1(int x)
{
int r , k , l ;
r = x ;
while( r != c[r] )
r = c[r] ;
k = x ;
while( k != r )
{
l = c[k] ; c[k] = r ; k = l ;
}
return r ;
}
int f(int s)
{
int i , j , u , v , num[maxn] , sum = 0 ;
memset(num,0,sizeof(num));
for(i = 1 ; i <= n ; i++)
c[i] = i ;
for(i = 1 ; i <= n ; i++)
{
for(j = head[i] ; j != -1 ; j = edge[j].next)
{
if( edge[j].u == s || edge[j].v == s )
continue ;
u = find1( edge[j].u ) ;
v = find1( edge[j].v ) ;
if(u != v)
c[u] = v ;
}
}
for(i = 1 ; i <= n ; i++)
{
if( head[i] != -1 && i != s )
{
num[ find1(i) ]++ ;
}
}
for(i = 1 ; i <= n ; i++)
if( num[i] )
sum++ ;
return sum ;
}
void tarjan(int u)
{
dnf[u] = low[u] = ++time ;
int v, i ;
for(i = head[u] ; i != -1 ; i = edge[i].next)
{
if( vis[i] ) continue ;
vis[i] = vis[i^1] = 1 ;
v = edge[i].v ;
if( !dnf[v] )
{
sta.push(i);
tarjan(v);
low[u] = min( low[u],low[v] );
if( low[v] >= dnf[u] && !ans[u] )
{
ans[u] = f(u);
}
}
else if( dnf[v] < dnf[u] )
low[u] = min( low[u],dnf[v] );
}
}
int main()
{
int u , v , temp = 0 , i;
while(scanf("%d", &u) && u)
{
temp++ ;
init();
scanf("%d", &v);
add(u,v);
n = max(n,u);
n = max(n,v);
while(scanf("%d", &u) && u)
{
scanf("%d", &v);
add(u,v);
n = max(n,u);
n = max(n,v);
}
tarjan(1);
int flag = 0 ;
printf("Network #%d\n", temp);
for(i = 1 ; i <= n ; i++)
if( ans[i] > 1 )
{
printf(" SPF node %d leaves %d subnets\n", i, ans[i]);
flag = 1 ;
}
if( !flag )
printf(" No SPF nodes\n\n");
else
printf("\n");
}
return 0;
}
原文:http://blog.csdn.net/winddreams/article/details/38844819