点双连通

 

 1 #include <cstdio>
 2 #include <vector>
 3 using namespace std;
 4 
 5 const int N = 1000+10;
 6 const int M = N*N;
 7 
 8 struct Edge {
 9     int u, v;
10     Edge( int u, int v ):u(u),v(v){}
11 };
12 
13 int n, m;
14 int head[N], dest[M], next[M], etot;
15 int dfn[N], low[N], bccno[N], iscut[N], bcc_cnt, idc;
16 vector<int> bcc[N];
17 vector<Edge> stk;
18 
19 void adde( int u, int v ) {
20     etot++;
21     dest[etot] = v;
22     next[etot] = head[u];
23     head[u] = etot;
24 }
25 void dfs( int u, int fa ) {
26     dfn[u] = low[u] = ++idc;
27     int child = 0;
28     for( int t=head[u]; t; t=next[t] ) {
29         int v=dest[t];
30         if( v==fa ) continue;
31         stk.push_back( Edge(u,v) );
32         if( !dfn[v] ) {
33             dfs(v,u);
34             low[u] = min( low[u], low[v] );
35             child++;
36             if( low[v]>=dfn[u] ) {
37                 iscut[u] = true;
38                 bcc_cnt++;
39                 while(1) {
40                     Edge e=stk.back();
41                     stk.pop_back();
42                     if( !bccno[e.u] ) bccno[e.u]=bcc_cnt,bcc[bcc_cnt].push_back(e.u);
43                     if( !bccno[e.v] ) bccno[e.v]=bcc_cnt,bcc[bcc_cnt].push_back(e.v);
44                     if( e.u==u && e.v==v ) break;
45                 }
46             }
47         } else if( dfn[v]<dfn[u] ) {
48             low[u] = min( low[u], dfn[v] );
49         }
50     }
51     if( u==fa && child<=1 ) iscut[u]=false;
52 }
53 int main() {
54     scanf( "%d%d", &n, &m );
55     for( int i=1,u,v; i<=m; i++ ) {
56         scanf( "%d%d", &u, &v );
57         adde( u, v );
58         adde( v, u );
59     }
60     dfs(1,1);
61     for( int u=1; u<=n; u++ )
62         if( iscut[u] ) printf( "%d ", u );
63     printf( "\n" );
64 }
View Code

 

posted @ 2015-07-14 18:06 idy002 阅读(...) 评论(...) 编辑 收藏