• 图的割点


    传送门:https://www.luogu.org/problem/P3388

    还有两点要注意的

    1.割点可能有很多个

    2.无向图和有向图都有割点

    然后我们来看一看如何实现割点

    方案一:枚举去掉每个点的情况,DFS判断时间复杂度O(n^2)

    方案二:Tarjan实现

    同样是用dfn表示搜索次序,但是low表示可以最早回溯到的祖先的dfn值

    之后就和tarjan没有太多不同了

    #include<bits/stdc++.h>
    using namespace std;
    int n,m;
    struct edge{
        int next,to;
    }e[200009];int tot;
    int first[100009];
    int dfn[100009];
    int low[100009];
    int js;
    int ans;
    bool book[100009];
    inline void add_edge(int a,int b)
    {
        e[++tot].to=b;
        e[tot].next=first[a];
        first[a]=tot;
    }
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        return x*f;
    }
    void tarjan(int now,int fa)//now是我在那里,fa是我的爸爸是谁
    {
        js++;
        dfn[now]=js,low[now]=js;
        int child=0;//记录有几个子树
        for(int i=first[now];i;i=e[i].next)
        {
            if(dfn[e[i].to]==0)
            {
                tarjan(e[i].to,now);
                if(low[now]>low[e[i].to])low[now]=low[e[i].to];
                if(now==fa)child++;//如果是根结点就+1
                if(now!=fa&&low[e[i].to]>=dfn[now])book[now]=true;//如果不是根结点并且它的子节点不通过它就无法回到之前的节点,那么说明它就是割点
            }
            else if(e[i].to!=fa&&dfn[e[i].to]<=low[now])
            {
                low[now]=dfn[e[i].to];
            }
        }
        if(now==fa&&child>=2)book[now]=true;//如果是根结点,并且儿子数量有两个以上那么明显就是割点
        return;
    }
    int main() {
        n=read(),m=read();
        for(register int i=1;i<=m;i++)
        {
            int a=read(),b=read();
            add_edge(a,b);
            add_edge(b,a);
        }
        for(int i=1;i<=n;i++)
        {
            if(dfn[i]==0)
            {
                tarjan(i,i);//因为割点有多个,并且图可能本身不连通,所以多次枚举
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(book[i]==true)ans++;
        }
        cout<<ans<<endl;
        for(int i=1;i<=n;i++)
        {
            if(book[i]==true)
            {
                cout<<i<<" ";
            }
        }
        return 0;
    }
  • 相关阅读:
    Handler机制来处理子线程去更新UI线程控件
    获得某月份的天数
    listview选中没有效果
    kali或其他系统,虚拟机中不能加载镜像
    tomcat开启多个端口
    kali自定义分辨率
    Redis 安装手册
    bash检查centos服务器运行状态
    关于利用RD client远程电脑,和输入法的一些问题
    centOS下 MYSQL基本操作
  • 原文地址:https://www.cnblogs.com/1129-tangqiyuan/p/11707801.html
Copyright © 2020-2023  润新知