Poj--1144(割顶)

2014-10-27 12:18:44

思路:求割顶裸题,这里的算法和scc的tarjan算法是在太像了,有异曲同工的妙。

  理下思路:(1)链前向星建图(2)选根DFS(3)每个点都有low和dfn(时间戳)值(4)如果以u点的任一子节点为根的子树中没有一个点有返回u的祖先的反向边,那么u为割顶。

(5)如果u为根节点且只有一个子节点,那么u为割顶。

 1 /*************************************************************************
 2     > File Name: 1144.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com 
 5     > Created Time: Sun 26 Oct 2014 08:49:00 PM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <vector>
13 #include <map>
14 #include <set>
15 #include <stack>
16 #include <queue>
17 #include <iostream>
18 #include <algorithm>
19 using namespace std;
20 #define lp (p << 1)
21 #define rp (p << 1|1)
22 #define getmid(l,r) (l + (r - l) / 2)
23 #define MP(a,b) make_pair(a,b)
24 typedef long long ll;
25 const int INF = 1 << 30;
26 const int maxn = 105;
27 
28 int N;
29 int first[maxn],next[maxn * maxn],ver[maxn * maxn],ecnt;
30 int low[maxn],iscut[maxn],dfn[maxn],tot;
31 
32 void Add_edge(int u,int v){
33     next[++ecnt] = first[u];
34     ver[ecnt] = v;
35     first[u] = ecnt;
36 }
37 
38 void Dfs(int p,int pre){
39     low[p] = dfn[p] = ++tot;
40     int son = 0;
41     for(int i = first[p]; ~i; i = next[i]){
42         int v = ver[i];
43         if(!dfn[v]){
44             ++son;
45             Dfs(v,p);
46             low[p] = min(low[p],low[v]);
47             if(low[v] >= dfn[p]){
48                 iscut[p] = 1;
49             }
50         }
51         else if(dfn[v] < dfn[p] && v != pre){
52             low[p] = min(low[p],dfn[v]);
53         }
54     }
55     if(pre < 0 && son == 1) iscut[p] = 0;
56 }
57 
58 void Init(){
59     memset(low,0,sizeof(low));
60     memset(dfn,0,sizeof(dfn));
61     memset(iscut,0,sizeof(iscut));
62     memset(first,-1,sizeof(first));
63     ecnt = tot = 0;
64 }
65 
66 int main(){
67     char c;
68     int a,b;
69     while(scanf("%d",&N) != EOF && N){
70         Init();
71         while(scanf("%d",&a) != EOF && a){
72             while(~scanf("%d%c",&b,&c)){
73                 Add_edge(a,b);
74                 Add_edge(b,a);
75                 if(c == '\n') break;
76             }
77         }
78         Dfs(1,-1);
79         int ans = 0;
80         for(int i = 1; i <= N; ++i)
81             ans += iscut[i];
82         printf("%d\n",ans);
83     }
84     return 0;
85 }

 

posted @ 2014-10-27 12:21  Naturain  阅读(236)  评论(0编辑  收藏  举报