fafu 1181 割点

http://acm.fafu.edu.cn/problem.php?id=1181

 

View Code
//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;

}

 

你可能感兴趣的:(a)