哈理工oj(acm.hrbust.edu.cn) 1494 ,zoj1311,poj1144【求割点,Targan算法】
裸的Targan算法,参考《图论算法理论、实现及应用》主编:王桂平 北大出版社 P387 仔细看,多看两遍,理解透彻。
View Code
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int MAXN = 100 + 10; int Edge[MAXN][MAXN]; int visited[MAXN]; int dfn[MAXN]; int low[MAXN]; int subnets[MAXN]; int nodes; //顶点数目。 int tmpdfn; //在dfs过程中记录当前的深度优先搜索序数。 int son; //根节点的子女节点的个数(如果大于2,则根节点是关节点). void dfs(int u) { for(int v = 1; v <= nodes; v++) { if( Edge[u][v] ) { if( !visited[v] ) { visited[v] = 1; tmpdfn++; dfn[v] = low[v] = tmpdfn; dfs( v ); low[u] = min(low[u], low[v]); if(low[v] >= dfn[u]) { if(u != 1) { subnets[u]++; } if(u == 1) { son++; } } } else { low[u] = min(low[u], dfn[v]); } } } } void init() { low[1] = dfn[1] = 1; tmpdfn = 1; son = 0; memset(visited, 0, sizeof(visited)); visited[1] = 1; memset(subnets, 0, sizeof(subnets)); } int main() { while(scanf("%d", &nodes), nodes) { memset(Edge, 0, sizeof(Edge)); while(1) { int u; scanf("%d%*c", &u); if( !u ) { break; } for(int i = 0; i <= nodes; i++) { char c; int v; scanf("%d", &v); c = getchar(); Edge[u][v] = Edge[v][u] = 1; if(c == '\n') { break; } } } init(); dfs(1); if( son > 1 ) { subnets[1] = son - 1; } int tot = 0; for(int i = 1; i <= nodes; i++) { if( subnets[i] ) { tot++; } } printf("%d\n", tot); } return 0; }