(beginer)DFS (双连通分量) UVA 10765 Doves and bombs

来源:互联网 发布:程序员帅哥 编辑:程序博客网 时间:2024/05/16 08:22

题意:给出一个图,一个点的“鸽子值”是删掉这个点后有多少个连通分量。求出每个点的鸽子值。

思路:如果一个点不是割顶,那么连通分量还是1,如果是割顶,那么连通分量的数目就是包含这个割顶的双连通分量的个数。所以直接模板吧。

代码:
#include<iostream>#include<cstring>#include<string.h>#include<cstdio>#include<stack>#include<algorithm>#include<vector>using namespace std;const int maxn = 10000+5;vector<int> G[maxn];int  pre[maxn] , dfs_clock;int n , m;struct Ans{Ans() { i = -1 ; cnt = 0; }int i;int cnt;}is_cut[maxn];bool cmp(const Ans & a1 , const Ans & a2){if (a1.cnt==a2.cnt) return a1.i < a2.i;return a1.cnt > a2.cnt;}int dfs(int u,int fa){int lowu = pre[u] = ++dfs_clock;int child = 0;for (int i = 0 ; i < G[u].size() ; ++i){int v = G[u][i];if (v==fa) continue;if (!pre[v]){++child;int lowv =  dfs(v,u);lowu =min(lowu,lowv);if (lowv >= pre[u]) {is_cut[u].i = u;is_cut[u].cnt++;}}else if (pre[u] > pre[v]) lowu = min(lowu,pre[v]);}if (fa < 0 && child==1) {is_cut[u].i = u;is_cut[u].cnt = 1;}return lowu;}void init(){dfs_clock = 0;memset(pre,0,sizeof(pre));for (int i = 0 ; i < n ; ++i) G[i].clear();}void input(){int u , v;while (scanf("%d%d",&u,&v)){if (u==-1 && v==-1) return;G[u].push_back(v);G[v].push_back(u);}}void solve(){for (int i = 0 ; i < n ; ++i) {is_cut[i].i = i;is_cut[i].cnt = 1;}is_cut[0].cnt = 0;dfs(0,-1);sort(is_cut,is_cut+n,cmp);for (int i = 0 ; i < m ; ++i) printf("%d %d\n",is_cut[i].i,is_cut[i].cnt);cout << endl;}int main(){while (scanf("%d%d",&n,&m),n+m){init();input();solve();}}


0 0