zoukankan      html  css  js  c++  java
  • 洛谷 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 <algorithm>
    #include <ctype.h>
    #include <cstring>
    #include <cstdio>
    #define N 100005
    using namespace std;
    void read(int &x)
    {
        x=0;char ch=getchar();
        while(!isdigit(ch)) ch=getchar();
        while(isdigit(ch))
        {
            x=x*10+ch-'0';
            ch=getchar();
        }
    }
    bool vis[N],cutpoint[N],cutedge[N];
    int ans[N],l,low[N],dfn[N],tim,n,m,cnt=-1,head[N];
    struct node
    {
        int next,to;
    }edge[N<<1];
    void add(int u,int v)
    {
        ++cnt;
        edge[cnt].next=head[u];
        edge[cnt].to=v;
        head[u]=cnt;
    }
    int min(int a,int b){return a>b?b:a;} 
    void tarjan(int x,int pre)
    {
        low[x]=dfn[x]=++tim;
        vis[x]=1;
        int sum=0;
        bool flag=false;
        for(int i=head[x];i!=-1;i=edge[i].next)
        {
            if((i^1)!=pre)
             if(!vis[edge[i].to])
             {
                 sum++;
                tarjan(edge[i].to,i);
                if(low[edge[i].to]>=dfn[x]) flag=true; 
                low[x]=min(low[x],low[edge[i].to]);
             }
             else low[x]=min(low[x],dfn[edge[i].to]);
        }
        if(pre==-1)
        {
            if(sum>1) cutpoint[x]=true;
        } 
        else
        {
            if(flag) cutpoint[x]=true;
        } 
    }
    int main()
    {
        memset(head,-1,sizeof(head));
        read(n);read(m);
        for(int x,y;m--;)
        {
            read(x);read(y);
            add(x,y);
            add(y,x);
        }
        for(int i=1;i<=n;i++)
            if(!vis[i]) tarjan(i,-1);
        for(int i=1;i<=n;i++)
            if(cutpoint[i]) l++,ans[l]=i;
        printf("%d
    ",l);
        for(int i=1;i<=l;i++) printf("%d ",ans[i]);
        return 0;
    }
    我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。
  • 相关阅读:
    Redis之通用的key操作命令
    Redis常用命令之操作Set(集合)
    Redis常用命令之操作SortedSet(有序集合)
    Redis常用命令之操作List类型
    Winform中实现监控CPU内存使用率(附代码下载)
    Ubuntu安装配置mongodb
    修改Ubuntu国内镜像
    redis安装和配置
    爬虫(十六):scrapy爬取知乎用户信息
    爬虫(十五):scrapy中的settings详解
  • 原文地址:https://www.cnblogs.com/ruojisun/p/6815668.html
Copyright © 2011-2022 走看看