无向图连通分量

割顶:

  POJ1144:求割顶的数量 

  1 #include <iostream>
  2 #include <string.h>
  3 #include <cstdio>
  4 #include <queue>
  5 #include <math.h>
  6 #include <cstring>
  7 #include <algorithm>
  8 #include <sstream>
  9 
 10 #define SIGMA_SIZE 26
 11 #pragma warning ( disable : 4996 )
 12 
 13 using namespace std;
 14 typedef long long LL;
 15 
 16 inline LL LMax(LL a,LL b)    { return a>b?a:b; }
 17 inline LL LMin(LL a,LL b)    { return a>b?b:a; }
 18 inline int Max(int a,int b) { return a>b?a:b; }
 19 inline int Min(int a,int b) { return a>b?b:a; }
 20 inline int gcd( int a, int b ) { return b==0?a:gcd(b,a%b); }
 21 inline int lcm( int a, int b ) { return a/gcd(a,b)*b; }  //a*b = gcd*lcm
 22 const int inf  = 0x3f3f3f3f;
 23 const int mod  = 7;
 24 const int maxn = 105;
 25 const int maxk = 200;
 26 
 27 
 28 int N, dfs_clock;
 29 vector<int> mmap[maxn];
 30 int low[maxn<<1], pre[maxn<<1];
 31 bool iscut[maxn];
 32 
 33 int dfs( int x, int fa )
 34 {
 35     int lowu = pre[x] = ++dfs_clock;
 36     int child = 0;
 37 
 38     for (int i = 0; i < mmap[x].size(); i++ )
 39     {
 40         int tmp = mmap[x][i];
 41         if ( !pre[tmp] )
 42         {
 43             child++;
 44             int lowv = dfs( tmp, x );
 45             lowu = Min(lowu, lowv);
 46 
 47             if ( lowv >= pre[x] )
 48                 iscut[x] = true;
 49         } else if ( pre[tmp] < pre[x] && tmp != fa )
 50             lowu = Min(lowu, pre[tmp]);
 51     }
 52 
 53     if ( fa < 0 && child == 1 ) iscut[x] = 0;
 54 
 55     low[x] = lowu;
 56     return lowu;
 57 }
 58 
 59 void init()
 60 {
 61     memset( mmap, 0, sizeof(mmap) );
 62     memset( pre, 0, sizeof(pre) );
 63     memset( iscut, 0, sizeof(iscut) ); 
 64 
 65     for( int i = 0; i < maxn; i++ )
 66         mmap[i].clear();
 67     dfs_clock = 0;
 68 }
 69 
 70 int main()
 71 {
 72     int x, y;
 73     string str;
 74     stringstream ss;
 75 
 76     while ( getline(cin, str) )
 77     {
 78         init();
 79         ss.clear(); ss << str;
 80         ss >> N;
 81         if (!N) break;
 82 
 83         
 84         while ( getline(cin, str) )
 85         {
 86 
 87             ss.clear(); ss << str;
 88             ss >> x;
 89 
 90             if ( !x ) break;
 91             while ( ss >> y )
 92                 { mmap[x].push_back(y); mmap[y].push_back(x); }
 93         }
 94 
 95         dfs(1,-1);
 96 
 97         int ans = 0;
 98         for( int i = 1; i <= N; i++ )
 99             if ( iscut[i] ) ans++;
100         cout << ans << endl;
101     }
102     
103     return 0;
104 }
View Code

 

转载于:https://www.cnblogs.com/chaoswr/p/8832605.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值