• 洛谷 P3388 【模板】割点(割顶)


    P3388 【模板】割点(割顶)

    题目背景

    割点

    题目描述

    给出一个nn个点,mm条边的无向图,求图的割点。

    输入格式

    第一行输入n,mn,m

    下面mm行每行输入x,yx,y表示xx到yy有一条边

    输出格式

    第一行输出割点个数

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

    输入输出样例

    输入 #1
    6 7
    1 2
    1 3
    1 4
    2 5
    3 5
    4 5
    5 6
    输出 #1
    1 
    5

    说明/提示

    对于全部数据,n ≤ 20000m100000

    点的编号均大于0小于等于n。

    tarjan图不一定联通。

    代码

     1 #include <bits/stdc++.h>
     2 #define ll long long
     3 #define ull unsigned long long
     4 #define ms(a,b) memset(a,b,sizeof(a))
     5 const int inf=0x3f3f3f3f;
     6 const ll INF=0x3f3f3f3f3f3f3f3f;
     7 const int maxn=1e6+10;
     8 const int mod=1e9+7;
     9 const int maxm=1e3+10;
    10 using namespace std;
    11 vector<int>ve[maxn];
    12 // dfn[u]表示顶点u第几个被访问(首次)
    13 int dfn[maxn];
    14 // low[u]表示顶点u及其子树中的点,通过非父子边(回边),能够回溯到的最早的点(dfn最小)的dfn值(但不能通过连接u与其父节点的边)
    15 // 对于边(u,v),如果low[v]>=dfn[u],则u是割点
    16 int low[maxn];
    17 int vis[maxn];
    18 int id;
    19 // if(u是v的子边)
    20 //     low[u]=min(low[u],low[v])
    21 // else
    22 //     low[u]=min(low[u],dfn[v])
    23 void tarjan(int u,int father)
    24 {
    25     int child=0;
    26     dfn[u]=low[u]=++id;
    27     int sz=ve[u].size();
    28     for(int i=0;i<sz;i++)
    29     {
    30         int v=ve[u][i];
    31         // 如果v未被访问过
    32         if(!dfn[v])
    33         {
    34             tarjan(v,father);
    35             low[u]=min(low[u],low[v]);
    36             // u是割点 
    37             if(low[v]>=dfn[u]&&u!=father)
    38                 vis[u]=1;
    39             if(u==father)
    40                 child++;
    41         }
    42         // 如果v被访问过,且u不是v的父亲
    43         low[u]=min(low[u],dfn[v]);
    44     }
    45     // u是根节点并且子树超过两个
    46     if(child>=2&&u==father)
    47         vis[u]=1;
    48 }
    49 int main(int argc, char const *argv[])
    50 {
    51     #ifndef ONLINE_JUDGE
    52         freopen("in.txt", "r", stdin);
    53         freopen("out.txt", "w", stdout);
    54         srand((unsigned int)time(NULL));
    55     #endif
    56     ios::sync_with_stdio(false);
    57     cin.tie(0);
    58     int n,m;
    59     cin>>n>>m;
    60     int x,y;
    61     while(m--)
    62     {
    63         cin>>x>>y;
    64         ve[x].push_back(y);
    65         ve[y].push_back(x);
    66     }
    67     for(int i=1;i<=n;i++)
    68         if(!dfn[i])
    69             tarjan(i,i);
    70     int ans=0;
    71     for(int i=1;i<=n;i++)
    72         if(vis[i])
    73             ans++;
    74     cout<<ans<<endl;
    75     for(int i=1;i<=n;i++)
    76         if(vis[i])
    77             cout<<i<<" ";
    78     cout<<endl;
    79     #ifndef ONLINE_JUDGE
    80         cerr<<"Time elapsed: "<<1.0*clock()/CLOCKS_PER_SEC<<" s."<<endl;
    81     #endif
    82     return 0;
    83 }
  • 相关阅读:
    Java工具类——UUIDUtils
    Python中的split()函数的用法
    学习笔记
    hdu 1558 线段相交+并查集
    hdu 4609 FFT
    hdu1402 FFT入门
    多项式乘法快速算法
    FFT
    GDUT校赛
    light oj 1236 分解质因数
  • 原文地址:https://www.cnblogs.com/Friends-A/p/11254325.html
Copyright © 2020-2023  润新知