码迷,mamicode.com
首页 > 其他好文 > 详细

5524 割点

时间:2016-11-08 23:04:21      阅读:227      评论:0      收藏:0      [点我收藏+]

标签:body   连通   img   ogg   分类   割点   default   media   efault   

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=15005;
vector<int>grap[N];
int n,m,pd,dfn[N],low[N],son,ans;
bool cut[N],mark[N];
void tarjan(int v,int root){
    dfn[v]=low[v]=++pd;
    mark[v]=1;
    for(int i=0;i<grap[v].size();i++){
        int w=grap[v][i];
        if(!dfn[w]){
            tarjan(w,root);
            low[v]=min(low[v],low[w]);
            if(low[w]>=dfn[v]&&v!=root) cut[v]=1;
            else if(v==root) son++;
        }
        else if(mark[w]){
            low[v]=min(low[v],dfn[w]);
        }
    }
}
int main(){
    scanf("%d%d",&n,&m);
    for(int x,y,i=1;i<=m;i++){
        scanf("%d%d",&x,&y);
        grap[x].push_back(y);
        grap[y].push_back(x);
    }
    for(int i=1;i<=n;i++) if(!dfn[i]){
        son=0;
        tarjan(i,i);
        if(son>1) cut[i]=1;
    }
    for(int i=1;i<=n;i++) if(cut[i]) ans++;
    printf("%d",ans);
    return 0;
}

 

5524 割点

标签:body   连通   img   ogg   分类   割点   default   media   efault   

原文地址:http://www.cnblogs.com/shenben/p/6044684.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!