http://acm.fafu.edu.cn/problem.php?id=1181
//fafu 1181 割点 //题目很明了 就是求割点数 #include <stdio.h> #include <string.h> #define N 1005 int n_node, n_edge, cnt, ans; int low[N], dep[N]; bool map[N][N]; void cutpoint(int son, int fa, int depth) { cnt++; int branch = 0; dep[son] = low[son] = depth; for(int i = 1; i <= n_node; ++i) { //son 可以到i 且 i不等于fa 才不会往回搜 if(map[son][i] == true && i != fa) { if(dep[i] == 0) { //若1 --> 2 -- > 3 --> 1 --> 4 有4这一分支时1是割点,没有4时, branch++; //1不是割点,所以1为起点的话要判断是否有两个或两个以上分支 cutpoint(i, son, depth+1); //若父亲son所能到的最小层数 大于孩子i所能到的最小层数 if(low[son] > low[i]) //则把son的最小层数更新为 i所 low[son] = low[i]; //能到的最小层数 //若孩子所能到的最小层数大于等于父亲son所在的层数 //或son为根节点(1)且分支数大于1,则son为割点 if(low[i] >= dep[son] && son != 1|| son == 1 && branch > 1) ans++; //记得则里判断条件是 大于等于,而求割边数是这里是大于 } else if(low[son] > low[i]) low[son] = low[i]; } } } int main() { while(scanf("%d%d", &n_node, &n_edge) != EOF) { memset(map, false, sizeof(map)); for(int i = 0; i < n_edge; ++i) { int a, b; scanf("%d%d", &a, &b); map[a][b] = map[b][a] = true; } ans = cnt = 0; memset(dep, 0, sizeof(dep)); cutpoint(1, -1, 1); //令1 为根节点,-1为1的父亲,深度为1 if(cnt < n_node) //若遍历过的点数少于总的节点数(即不联通) puts("-1"); else printf("%d\n", ans); } return 0; }