坐井观天

In the name of dream

导航

POJ 3177 缩点 + 边双连通图

Posted on 2012-06-10 17:02  一毛_  阅读(177)  评论(0编辑  收藏  举报

题目链接: http://poj.org/problem?id=3177

题目大意及分析:

  和我的上一篇博文一样的。

  好像我按照没有重边的来写的,ac了。

 

代码:

poj3177
 1 /*3177    Accepted    316K    0MS    C++    2191B    2012-06-10 16:29:42*/
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <iostream>
 6 #include <algorithm>
 7 #include <vector>
 8 using namespace std;
 9 
10 #define mpair make_pair
11 #define pii pair<int,int>
12 #define MM(a,b) memset(a,b,sizeof(a));
13 typedef long long lld;
14 typedef unsigned long long u64;
15 template<class T> bool up_max(T& a,const T& b){return b>a? a=b,1 : 0;}
16 template<class T> bool up_min(T& a,const T& b){return b<a? a=b,1 : 0;}
17 #define maxn 5020
18 
19 int n,m;
20 vector<int> g[maxn];
21 
22 int Bcnt, Index, Top;
23 int low[maxn], dfn[maxn], sta[maxn], beg[maxn];
24 bool vis[maxn];
25 void Init_dcc(){
26     Bcnt= Index= Top= 0;
27     for(int i=1;i<=n;++i) low[i]= dfn[i]= vis[i]= 0;
28 }
29 void dfs_dcc(int u,int fa){
30     low[u]= dfn[u]= ++Index;
31     sta[++Top]= u;
32     vis[u]= 1;
33     for(int i=0;i<g[u].size();++i){
34         int v= g[u][i];
35         if( v==fa ) continue;
36 
37         if( !dfn[v] ){
38             dfs_dcc( v, u );
39             up_min( low[u], low[v] );
40         }
41         else if( vis[v] )
42             up_min( low[u], dfn[v] );
43     }
44     if( low[u]==dfn[u] ){
45         ++Bcnt;
46         int v;
47         do{
48             v= sta[Top--];
49             vis[v]= 0;
50             beg[v]= Bcnt;
51         }while( v!=u );
52     }
53 }
54 
55 int degree[maxn];
56 void dfs(int u){
57     vis[u]= 1;
58     for(int i=0;i<g[u].size();++i){
59         int v= g[u][i];
60         if( !vis[v] ){
61             if( beg[v] != beg[u] ){
62                 ++degree[ beg[v] ];
63                 ++degree[ beg[u] ];
64             }
65             dfs(v);
66         }
67     }
68 }
69 
70 int main()
71 {
72     //freopen("poj3177.in","r",stdin);
73     while( cin>>n>>m ){
74         int i,x,y;
75         for(i=1;i<=n;++i) g[i].clear();
76         while( m-- ){
77             scanf("%d%d", &x, &y);
78             g[x].push_back(y);
79             g[y].push_back(x);
80         }
81         Init_dcc();
82         dfs_dcc( 1, 1 );
83         if( Bcnt<=2 ){
84             printf("%d\n", Bcnt-1);
85             continue;
86         }
87 
88         for(i=1;i<=Bcnt;++i) degree[i]= 0;
89         fill( vis, vis+1+n, 0 );
90         dfs( 1 );
91 
92         int leaf= 0;
93         for(i=1;i<=Bcnt;++i) if( degree[i]==1 ) leaf++;
94         printf("%d\n", (leaf+1)/2 );
95     }
96 }