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

    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 图不一定联通!!!

    分析

    tarjan求割点

    code

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<cstdlib>
     6 
     7 using namespace std;
     8 
     9 const int N = 100100;
    10 struct Edge{
    11     int to,nxt;
    12 }e[N<<1];
    13 int head[N],dfn[N],low[N];
    14 bool iscut[N];
    15 int tn,tot;
    16 
    17 inline char nc() {
    18     static char buf[100000],*p1 = buf,*p2 = buf;
    19     return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2) ? EOF : *p1++;
    20 }
    21 inline int read() {
    22     int x = 0,f = 1;char ch = nc();
    23     for (; ch<'0'||ch>'9'; ch = nc()) 
    24         if (ch=='-') f = -1;
    25     for (; ch>='0'&&ch<='9'; ch = nc()) 
    26         x = x*10+ch-'0';
    27     return x * f;
    28 }
    29 
    30 void add_edge(int u,int v) {
    31     e[++tot].to = v,e[tot].nxt = head[u],head[u] = tot;
    32 }
    33 
    34 void tarjan(int u,int fa) {
    35     low[u] = dfn[u] = ++tn;
    36     int cnt_son = 0;
    37     for (int i=head[u]; i; i=e[i].nxt) {
    38         int v = e[i].to;
    39         if (!dfn[v]) {
    40             cnt_son++;
    41             tarjan(v,u);
    42             low[u] = min(low[u],low[v]);
    43             if (low[v] >= dfn[u]) 
    44                 iscut[u] = true;
    45         }
    46         else if (dfn[v] < dfn[u] && v != fa) 
    47             low[u] = min(low[u],dfn[v]);
    48     }
    49     if (fa<0 && cnt_son==1) iscut[u] = false;
    50 }
    51 int main() {
    52     int n = read(),m = read();
    53     for (int u,v,i=1; i<=m; ++i) {
    54         u = read(),v = read();
    55         add_edge(u,v),add_edge(v,u);
    56     }
    57     for (int i=1; i<=n; ++i) 
    58         if (!dfn[i]) tarjan(i,-1);
    59 
    60     int ans = 0;
    61     for (int i=1; i<=n; ++i) 
    62         if (iscut[i]) ans++;
    63     printf("%d
    ",ans);
    64     for (int i=1; i<=n; ++i) 
    65         if (iscut[i]) printf("%d ",i);
    66     return 0;
    67 }
  • 相关阅读:
    线程安全好文章
    分布式事务
    jvm内存泄漏问题分析过程
    Java8--Lambda表达式
    ZK Watcher 的原理和实现
    JVM垃圾回收算法
    linux常用命令
    Excel常用函数汇总
    Debian 镜像使用帮助
    photon 下载地址
  • 原文地址:https://www.cnblogs.com/mjtcn/p/7895868.html
Copyright © 2011-2022 走看看