POJ1144-求图的割点(裸)

53 篇文章 1 订阅
#include <cstdio>
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;

const int NN=105;

vector<int> adj[NN];
int n,rt,rt_son;
int dfn[NN],low[NN];
bool cut[NN];

void dfs(int u,int dep)
{
    dfn[u]=low[u]=dep;
    for (int i=0; i<adj[u].size(); i++)
    {
        int v=adj[u][i];
        if (!dfn[v])
        {
            dfs(v,dep+1);
            if (u==rt) rt_son++;
            else
            {
                low[u]=min(low[u],low[v]);
                if (low[v]>=dfn[u]) cut[u]=true;  //由后继节点搜不到比该点更早的点,则该点是割点
            }
        }
        else low[u]=min(low[u],dfn[v]);
    }
}

int main()
{
    while (scanf("%d",&n)!=EOF && n)
    {
        for (int i=1; i<=n; i++) adj[i].clear();
        memset(dfn,0,sizeof(dfn));
        int u,v;
        while (scanf("%d",&u),u)
        {
            while (getchar()!='\n')
            {
                scanf("%d",&v);
                adj[u].push_back(v);
                adj[v].push_back(u);
            }
        }
        rt=1; rt_son=0;
        memset(cut,false,sizeof(cut));
        dfs(rt,1);  
        if (rt_son>1) cut[rt]=true;   //有两个子树的根是割点
        int sum=0;
        for (int i=1; i<=n; i++) sum+=cut[i];
        printf("%d\n",sum);
    }
    return 0;
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值