POJ 1144 Network(Tarjan)

题目链接

题意 : 找出割点个数。

思路 : Tarjan缩点,u是割点的充要条件是:u要么是具有两个以上子女的深度优先生成树的根,要么不是根,而有一个子女v满足low[v]>=dfn[u]。

 1 #include <cstdio>

 2 #include <cstring>

 3 #include <iostream>

 4 #include <algorithm>

 5 

 6 using namespace std ;

 7 

 8 int head[1010],fb[1010],low[1010],dfn[1010];

 9 int cnt,timee ,ans,son ;

10 struct node

11 {

12     int u ;

13     int v ;

14     int next ;

15 }p[1010];

16 

17 void addedge(int u,int v)

18 {

19     p[cnt].u = u ;

20     p[cnt].v = v ;

21     p[cnt].next = head[u] ;

22     head[u] = cnt ++ ;

23     p[cnt].u = v ;

24     p[cnt].v = u ;

25     p[cnt].next = head[v] ;

26     head[v] = cnt ++ ;

27 }

28 void Init()

29 {

30     cnt = timee = ans = son = 0 ;

31     memset(head,-1,sizeof(head)) ;

32     memset(dfn,0,sizeof(dfn)) ;

33     memset(low,0,sizeof(low)) ;

34     memset(fb,0,sizeof(fb)) ;

35 }

36 

37 void tarjan(int u)

38 {

39     dfn[u] = low[u] = ++timee  ;

40     for(int i = head[u] ; i != -1 ; i = p[i].next)

41     {

42         int v = p[i].v ;

43         if(dfn[v]) low[u] = min(low[u],dfn[v]) ;

44         else

45         {

46             tarjan(v) ;

47             low[u] = min(low[v],low[u]) ;

48             if(low[v] >= dfn[u])

49             {

50                 if(u == 1) son ++ ;

51                 else

52                 fb[u] = 1 ;

53             }

54         }

55     }

56 }

57 int main()

58 {

59     int n,m,s ;

60     while(~scanf("%d",&n))

61     {

62         if(n == 0 )break ;

63         Init() ;

64         while( ~scanf("%d",&m))

65         {

66             if(m == 0) break ;

67             while(getchar() != '\n')

68             {

69                 scanf("%d",&s) ;

70                 addedge(s,m) ;

71             }

72         }

73         tarjan(1) ;

74         if(son > 1) ans ++ ;

75         for(int i = 1 ; i <= n ; i++)

76             if(fb[i]) ans ++ ;

77         printf("%d\n",ans) ;

78     }

79     return 0 ;

80 }
View Code

 

你可能感兴趣的:(NetWork)