uva 10972(边双连通分量)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=33804

思路:和poj的一道题有点像,不过这道题图可能不连通,因此首先求边双连通分量,然后算每个连通分量的度数,显然叶子节点的度数为1,孤立点的度数为0,然后就是统计度数了,对于孤立点ans+=2,对于叶子节点,ans++。于是最后的答案就是(ans+1)/2了。

 1 #include <iostream>

 2 #include <cstdio>

 3 #include <cstring>

 4 #include <algorithm>

 5 #include <stack>

 6 #include <vector>

 7 using namespace std;

 8 #define MAXN 1111

 9 

10 int n, m, cnt, _count;

11 stack <int >S; 

12 vector <vector<int > >g;

13 

14 int low[MAXN], dfn[MAXN], color[MAXN];

15 int degree[MAXN];

16 bool mark[MAXN];

17 void Tarjan(int u, int father)

18 {

19     low[u] = dfn[u] = ++ cnt;

20     S.push(u);

21     mark[u] = true;

22     for(int i = 0; i < g[u].size(); i ++ ){

23         int v = g[u][i];

24         if(v == father)continue;

25         if(dfn[v] == 0) {

26             Tarjan(v, u);

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

28         } else if(mark[v]) {

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

30         }

31     }

32     if(low[u] == dfn[u]){

33         int x;

34         _count++;

35         do {

36             x = S.top();

37             S.pop();

38             mark[x] = false;

39             color[x] = _count;

40         }while(x != u);

41     }

42 }

43 

44 int main()

45 {

46     int u, v, ans;

47     while(~scanf("%d %d", &n, &m)){

48         g.clear();

49         g.resize(n+2);

50         while(m --){

51             scanf("%d %d",&u, &v);

52             g[u].push_back(v);

53             g[v].push_back(u);

54         }

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

56         memset(mark, false, sizeof(mark));

57         cnt = _count = 0;

58         for(int i = 1; i <= n; i ++){

59             if(dfn[i] == 0)Tarjan(i, -1);

60         }

61         if(_count == 1){

62             puts("0");

63             continue;

64         }

65         memset(degree, 0, sizeof(degree));

66         for(int i = 1; i <= n; i++){

67             for(int j = 0; j < g[i].size(); j++){

68                 if(color[i] != color[g[i][j]])degree[color[g[i][j]]] ++;

69             }

70         }

71         ans = 0;

72         for(int i = 1; i <= _count; i++){

73             if(degree[i] == 0)ans += 2; // 孤立点

74             else if(degree[i] == 1)ans ++; // 叶子节点

75         }

76         printf("%d\n", (ans + 1)/2 );

77     }

78     return 0;

79 }
View Code

 

你可能感兴趣的:(uva)