zoukankan      html  css  js  c++  java
  • luogu P3388 【模板】割点(割顶)

    题目背景

    割点

    题目描述

    给出一个n个点,m条边的无向图,求图的割点。

    输入输出格式

    输入格式:

    第一行输入n,m

    下面m行每行输入x,y表示x到y有一条边

    输出格式:

    第一行输出割点个数

    第二行按照节点编号从小到大输出节点,用空格隔开

    输入输出样例

    输入样例#1:
    6 7
    1 2
    1 3
    1 4
    2 5
    3 5
    4 5
    5 6
    输出样例#1:
    1 
    5

    说明

    n,m均为100000

    tarjan 图不一定联通!!!

    #include<cstdio>
    #include<algorithm>
    
    #define N (1000000+10)
    using namespace std;
    
    int a[N],nxt[N],head[N],dfn[N],low[N],cnt,k;
    bool cut[N],bst[N];
    
    void add(int x,int y)
    {
        a[++k]=y; nxt[k]=head[x]; head[x]=k;
    }
    
    void tarjan(int u,int mr)
    {
        int rc=0;
        dfn[u]=low[u]=++cnt;
        for (int p=head[u];p;p=nxt[p])
    	{
            int v=a[p];
            if (!dfn[v])
    		{
                tarjan(v,mr);
                low[u]=min(low[u],low[v]);
                if (low[v]>=dfn[u]&&u!=mr) 
    				cut[u]=true;
                if (u==mr) rc++;//根节点的孩子 
            }
            low[u]=min(low[u],dfn[v]);
        }    
        if (u==mr&&rc>=2)
    		cut[mr]=true;
    }
    
    int main()
    {
        int n,m,ans=0;
        scanf("%d%d",&n,&m);
        for (int i=1;i<=m;i++)
    	{
            int x,y;
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
        }
        for (int i=1;i<=n;i++)
    	{
            if (!dfn[i]) tarjan(i,i);//防止遗漏 
        }
        for (int i=1;i<=n;i++) 
    		if (cut[i]) ans++;
        printf("%d
    ",ans);
        for (int i=1;i<=n;i++) 
    		if (cut[i]) printf("%d ",i);
    	return 0;
    }
    

      

  • 相关阅读:
    校园网络(tarjan)
    消息扩散(强连通分量)
    上帝造题的七分钟(树桩数组乱搞)
    数颜色 / 维护队列(带修莫队)
    Luogu5155 [USACO18DEC]Balance Beam
    分数规划小结
    Luogu3177 [HAOI2015]树上染色
    Luogu4402 机械排序
    Luogu3201 [HNOI2009]梦幻布丁
    Luogu3380 二逼平衡树
  • 原文地址:https://www.cnblogs.com/lyqlyq/p/7354002.html
Copyright © 2011-2022 走看看