18.1.17割点

原题链接:https://www.luogu.org/problemnew/show/3388

割点的tarjan算法:
选定一个节点为根节点,遍历整个图,形成一棵树
根节点若有两个子树,则其一定是割点。
对于不是根节点的节点,维护两个数组dfn与low
dfs[u]表示节点u第几个被访问,low[u]表示节点u最早能回溯到的边
对于边(u, v),如果low[v]>=dfn[u],此时u就是割点。
边(u,v),如果v未访问过,dfs之后,更新:low[u]=min(low[u],low[v]);
访问过,无需dfs,一定有dfn[v]<dfn[u],更新:low[u]=min(low[u], dfn[v])。

值得一提的是,luogu的割点模板题图可能不连通,而且最后还要按顺序输出,所以,记录好根节点与非根节点,然后最后sort一下。

#include<cstdio>
#include<algorithm>
using namespace std;
void read(int &y)
{
    y=0;char x=getchar();
    while(x<‘0‘||x>‘9‘) x=getchar();
    while(x>=‘0‘&&x<=‘9‘)
    {
        y=y*10+x-‘0‘;
        x=getchar();
    }
}
int n,m,x,y,cnt,tot,ans;
struct edge
{
    int u,v;
}e[200005];
int head[100005],va[100005];
int dfn[100005],low[100005],q[100005];
int fa[100005],vis[100005],rot[100005];
void add(int u,int v)
{
    e[++cnt].u=head[u];
    e[cnt].v=v;
    head[u]=cnt;
}
void dfs(int u)
{
    dfn[u]=low[u]=++tot;
    vis[u]++;
    for(int i=head[u];i;i=e[i].u)
    {
        int v=e[i].v;
        if(vis[v]==0)
        {
            rot[u]++;
            fa[v]=u;
            dfs(v);
            low[u]=min(low[u],low[v]);
            if((vis[u]==2&&rot[u]>1)||(vis[u]==1&&low[v]>=dfn[u]))
            {
                if(va[u]) continue;
                va[u]=1;
                q[++ans]=u;
            }
        }
        else if(v!=fa[u]) low[u]=min(low[u],dfn[v]);
    }
}
int main()
{
//    freopen("testdata.in","r",stdin);
    read(n);read(m);
    for(int i=1;i<=m;i++)
    {
        read(x);read(y);
        add(x,y);add(y,x);
    }
    for(int i=1;i<=n;i++)
    {
        if(vis[i]==0)
        {
            vis[i]++;
            dfs(i);
        }
    }
    printf("%d\n",ans);
    sort(q+1,q+ans+1);
    for(int i=1;i<=ans;i++) printf("%d ",q[i]);
    return 0;
}

原文地址:https://www.cnblogs.com/zeroform/p/8302561.html

时间: 2024-11-08 20:46:20

18.1.17割点的相关文章

18.9.17 poj2492 A Bug&#39;s Life

描述 BackgroundProfessor Hopper is researching the sexual behavior of a rare species of bugs. He assumes that they feature two different genders and that they only interact with bugs of the opposite gender. In his experiment, individual bugs and their

18.12.17 POJ 1569 Myacm Triangles

描述 There has been considerable archeological work on the ancient Myacm culture. Many artifacts have been found in what have been called power fields: a fairly small area, less than 100 meters square where there are from four to fifteen tall monuments

18.12.17 POJ 1269 Intersecting Lines

描述 We all know that a pair of distinct points on a plane defines a line and that a pair of lines on a plane will intersect in one of three ways: 1) no intersection because they are parallel, 2) intersect in a line because they are on top of one anoth

18.07.17

一.函数名的运用 函数名是一个变量,但它是一个特殊的变量,与括号配合可以执行函数的变量. 1.函数名可以赋值给其他变量 例: def fn(): print("abc")print(fn) #函数的内存地址a = fn #将函数赋值给aa() #调用函数==> <function fn at 0x00000229C37C2AE8> abc 2.函数可以作为函数的参数 例: def func(fn): fn()def gn(): print("abc"

18.8.17 考试总结

高斯消元[问题描述]everlasting 觉得太无聊了,于是决定自己玩游戏! 他拿出了n 个小圆,第i 个的颜色是ai.接着他将这n 个小圆复制m 次并依次连接起来. 之后他发现其中有很多颜色相同的小圆,于是他决定:每有k 个连续颜色相同的小圆就将他们消去, 并将剩下的依次连接.(注意只会消除k个,即使有超过k 个)他将每次从头开始不断进行这个操作直到无法操作为止. 他想知道最后能剩下多少个小圆? [输入格式] 从文件guass.in 中输入数据. 第一行三个正整数n,m,k,表示开始小圆的个

18.10.17 考试总结

今天心态崩崩,,,.. 这道题比较简单 因为每一位是单独对答案产生贡献的 所以枚举每一位 用数位dp求出该位是$1$的数量 在求出该位是$0$的 那么答案就是那一位对应的二的幂次再乘以$num1 * num0 * 2$ 每一对会产生两次贡献 代码 #include <bits/stdc++.h> #define rg register #define il inline using namespace std; typedef long long ll; const ll MOD = 1e9

原程序员的算法课(1)-算法概述2019年08月18日 17:58:49 十步杀一人_千里不留行 阅读数 11更多所属专栏: 程序员的算法课编辑

[算法之美]数据结构+算法=程序. 前言 数据结构只是静态的描述了数据元素之间的关系.高效的程序需要在数据结构的基础上设计和选择算法. 高效的程序=恰当的数据结构+合适的算法 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制.也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出.如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题.不同的算法可能用不同的时间.空间或效率来完成同样的任务.一

身份证号码为15位或者18位,15位时全为数字,18位前17位为数字,最后一位是校验位,可能为数字或字符X

function checkIdCardNo(idCardNo) { // 身份证号码为15位或者18位,15位时全为数字,18位前17位为数字,最后一位是校验位,可能为数字或字符X var reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/; if (reg.test(idCardNo) === false) { wx.showToast({ title: '身份证号码不正确!', icon: 'none', }) return false; }

JavaSE学习总结第17天_集合框架3

17.01 ArrayList集合的toString()方法源码解析 代码: Collection c = new ArrayList(); c.add("hello"); c.add("world"); c.add("java");   System.out.println(c);    输出c时默认调用的是c的toString()方法 A:Collection c = new ArrayList(); 这是多态,所以输出c的 toString