fafu 1180 割边

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

 

View Code
//fafu 1180  割边



//low[i]表示i或i的子孙可以到达的最小深度

//若可到达的最小深度比父亲节点的深度来的高,则出现割边



#include <stdio.h>

#include <string.h>



#define N 1005



int n_node, n_edge, cnt, ans;

int low[N], depth[N];

bool map[N][N];



void cutline(int son, int fa, int dep)

{

    low[son] = depth[son] = dep;



    for(int i = 1; i <= n_node; ++i)

    {   //i!=fa 表示不能往回搜

        if(i != fa && map[son][i] == true)

        {

            if(depth[i] == 0)   //相当于标记是否遍历过

            {

                cnt++;  //记录遍历过的点数,若小于总的点数则不联通



                cutline(i, son, dep+1);

                //回溯回来,若儿子能到的深度比父亲的低,则

                //父亲指向儿子所指向的深度

                if(low[son] > low[i])

                    low[son] = low[i];

        //若儿子节点 i指向的最小深度大于父节点son的深度则为割边

                if(low[i] > depth[son])

                    ans++;

            }   //如果i 节点遍历过了(即表示形成环),则看son节点指向的最小深度

            else if(low[son] > low[i])  //有没有小于 i指向的最小深度,现在i 是son的孩子

                low[son] = low[i];   //则把 son指向的最小深度 更改为 i指向的最小深度

        }

    }

}



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;

        }



        cnt = 1;

        ans = 0;

        memset(depth, 0, sizeof(depth));

        cutline(1, -1, 1);  //令 1为根节点,-1为1 的父节点

        if(cnt < n_node)

            puts("-1");

        else

            printf("%d\n", ans);

    }

    return 0;

}

 

 

你可能感兴趣的:(a)