5524 割点

本文介绍了一种求解图中所有连通分量中割点总数的算法,并提供了详细的AC代码实现。通过DFS遍历图,利用Tarjan算法识别割点,最终计算并输出割点数量。

5524 割点

 

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 钻石 Diamond
 
 
 
题目描述  Description

给你一个图,这个图本身可能不是连通的,你要做的是求出图中所有连通分量中割点的总和。

输入描述  Input Description

第一行两个正整数N M,表示图有N个顶点,M条边,

接下来M行,每行两个整数a b,表示a,b之间有一条双向边。

输出描述  Output Description

输出一共包括一行,表示每个分量中割点的总和。

样例输入  Sample Input

5 5 

1 2 

2 3 

4 3 

4 5 

2 5

 

样例输出  Sample Output

1

数据范围及提示  Data Size & Hint

样例如图所示,唯一的割点为点2。

对于30%的数据,n,m<=101;

对于100%的数据,n,m<=15001;

分类标签 Tags 点此展开 

 求割点的模板

原理:传送门

AC代码:

 

#include<cstdio>
#include<vector>
using namespace std;
const int N=1e5+10;
struct node{
    int v,next;
}e[N<<1];int tot;
int n,m,pd,kid,head[N],dfn[N],low[N],fa[N],ans;
bool cut[N],mark[N];
void add(int x,int y){
    e[++tot]=(node){y,head[x]};
    head[x]=tot;
}
void tarjan(int x){
    dfn[x]=low[x]=++pd;
    int kid=0;bool flag=0;
    for(int i=head[x];i;i=e[i].next){
        int v=e[i].v;
        if(fa[x]!=v){
            if(!dfn[v]){
                kid++;
                fa[v]=x;
                tarjan(v);
                low[x]=min(low[x],low[v]);
                if(fa[x]!=-1&&low[v]>=dfn[x]) flag=1;
            }
            else low[x]=min(low[x],dfn[v]);
        }
    }
    if((fa[x]==-1&&kid>1)||flag) cut[x]=1;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int x,y,i=1;i<=m;i++){
        scanf("%d%d",&x,&y);
        add(x,y);add(y,x);
    }
    for(int i=1;i<=n;i++) if(!dfn[i]) fa[i]=-1,tarjan(i);
    for(int i=1;i<=n;i++) if(cut[i]) ans++;
    printf("%d",ans);
    return 0;
}

 

 

 

转载于:https://www.cnblogs.com/shenben/p/6044684.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值