/* *State: POJ1144 224K 94MS C++ 1735B *题目大意: * 求无向图的割点。 *解题思路: * 就输入比较奇葩,要处理下字符串而已。注意判断一个点是割点,要具备两个 * 条件,一个是dfs树的根节点(比较特殊,注意减1,按tarjan去理解即可) * ,一个是dfs中的子节点。 */
View Code
1 #include <iostream> 2 #include <vector> 3 #include <cstdio> 4 #include <cstring> 5 #include <string> 6 #include <sstream> 7 using namespace std; 8 9 const int MAX = 105; 10 vector<int> vec[MAX]; 11 int dfn[MAX], low[MAX], step, spf[MAX]; 12 13 void addEdge(int u, int v) 14 { 15 vec[u].push_back(v); 16 vec[v].push_back(u); 17 } 18 19 void dealinput(char str[]) 20 { 21 string ss = str; 22 istringstream line(ss); 23 int u, v; 24 line >> u; 25 while(line >> v) 26 addEdge(u, v); 27 } 28 29 void tarjan(int n) 30 { 31 dfn[n] = low[n] = ++step; 32 for(unsigned i = 0; i < vec[n].size(); i++) 33 { 34 int son = vec[n][i]; 35 if(dfn[son] == -1) 36 { 37 tarjan(son); 38 if(dfn[n] <= low[son]) 39 spf[n]++; 40 else 41 low[n] = min(low[n], low[son]); 42 } 43 else 44 low[n] = min(low[n], dfn[son]); 45 } 46 } 47 48 void view_arr(int spf[]) 49 { 50 for(int i = 0; i < 10; i++) 51 cout << spf[i] << " "; 52 cout << endl; 53 } 54 55 void init() 56 { 57 step = 0; 58 for(int i = 0; i < MAX; i++) 59 { 60 vec[i].clear(); 61 dfn[i] = low[i] = -1; 62 spf[i] = 0; 63 } 64 } 65 66 int main(void) 67 { 68 #ifndef ONLINE_JUDGE 69 freopen("in1144.txt", "r", stdin); 70 #endif 71 int n; 72 while(scanf("%d", &n), n) 73 { 74 init(); 75 int u, v; 76 char input[MAX * 5]; 77 getchar(); 78 while(gets(input)) 79 { 80 if(input[0] == '0') 81 break; 82 dealinput(input); 83 } 84 tarjan(1); 85 spf[1]--; 86 int cnt = 0; 87 for(int i = 1; i < MAX; i++) 88 { 89 if(spf[i] > 0) 90 { 91 cnt++; 92 } 93 } 94 printf("%d\n", cnt); 95 } 96 return 0; 97 }