TOJ.1026 Network【求无向图割点】

        题目大意是一个公司有一个网络,连接着从编号1到N共N个地方,然后给出一些边,表示哪两个地方相连。有些点一旦断开所有和它关联的边,那么图不再联通,称这样的点为“critical  place”,求有多少个这样的点。

 

/* DFS求割点,在DFS时记录每个节点的深度dep和它的子孙所能达到的最浅位置low
 * 1)如果u根节点儿子大于1个,根节点为割点
 * 2)如果u不是根节点且对于u的子孙v有low[v]>=dep[u],u为一个割点
 * 注意输入和输出(输入用getchar() != '/n' 来控制一行 )
 */

 

#include <cstdio> #include <cstring> #define M 102 using namespace std; int map[M][M],low[M],dep[M]; int f[M],n,depth,root; bool flag[M]; int min(int a,int b){ return a<b?a:b; } void dfs(int m){ dep[m] = depth; low[m] = depth; depth++; flag[m] = true; int i,j,k; for(i = 1;i <= n; i++){ if(map[m][i]){ if(!flag[i]){ dfs(i); low[m] = min(low[m],low[i]); if(low[i] >= dep[m] && m != 1) f[m] ++; //if low[i] >= dep[m]且m不是根节点,m是割点 else if(m == 1) root ++; } else //有后向边 low[m] = min(low[m],dep[i]); } } } int main() { int i,j,k; while(scanf("%d",&n),n){ memset(map,0,sizeof(map)); memset(f,0,sizeof(f)); memset(low,0,sizeof(low)); memset(flag,false,sizeof(flag)); memset(dep,0,sizeof(dep)); root = 0; while(scanf("%d",&k),k){ while(getchar() != '/n'){ scanf("%d",&j); map[k][j] = map[j][k] = 1; } } root = 0; depth = 1; dfs(1); int ans = 0; if(root > 1) ans ++; for(i = 2;i <= n; i++) if(f[i]) ans ++; printf("%d/n",ans); } }

你可能感兴趣的:(网络,NetWork)