uva 10972(边双连通分量)

来源:互联网 发布:声学模拟软件 编辑:程序博客网 时间:2024/05/16 16:08

题目链接: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

 

0 0
原创粉丝点击