码迷,mamicode.com
首页 > 其他好文 > 详细

「模板」 割点

时间:2018-05-15 19:35:34      阅读:158      评论:0      收藏:0      [点我收藏+]

标签:add   block   www.   argv   org   void   ble   ges   head   

「模板」 割点

<题目链接>


不会点双导致的 APIO 完挂。

本应该联赛前学的东西,不及时学,就只有等到变回联赛选手后再学了吧。

以及,以后放弃链式前向星,存图一律指针邻接表。

#include <algorithm>
#include <cstdio>
using std::min;
const int MAXN=100010;
bool cut[MAXN];
int n,m,DFN_num,ans,DFN[MAXN],low[MAXN];
struct Edge
{
    int to;
    Edge *nxt;
    Edge(int to=0,Edge* nxt=nullptr):to(to),nxt(nxt){}
    ~Edge(void)
    {
        if(nxt!=nullptr)
            delete nxt;
    }
}*head[MAXN];
void AddEdge(int u,int v)
{
    head[u]=new Edge(v,head[u]);
}
void AddEdges(int u,int v)
{
    AddEdge(u,v);
    AddEdge(v,u);
}
void Tarjan(int u,int father)
{
    int st_num=0;
    DFN[u]=low[u]=++DFN_num;
    for(Edge *i=head[u];i!=nullptr;i=i->nxt)
    {
        int v=i->to;
        if(!DFN[v])
        {
            Tarjan(v,father);
            low[u]=min(low[u],low[v]);
            if(DFN[u]<=low[v] && u!=father)
                cut[u]=true;
            if(u==father)
                ++st_num;
        }
        low[u]=min(low[u],DFN[v]);
    }
    if(u==father && st_num>1)
        cut[father]=true;
}
int main(int argc,char** argv)
{
    scanf("%d %d",&n,&m);
    for(int i=1,x,y;i<=m;++i)
    {
        scanf("%d %d",&x,&y);
        AddEdges(x,y);
    }
    for(int i=1;i<=n;++i)
        if(!DFN[i])
            Tarjan(i,i);
    for(int i=1;i<=n;++i)
        if(cut[i])
            ++ans;
    printf("%d\n",ans);
    for(int i=1;i<=n;++i)
    {
        if(cut[i])
            printf("%d ",i);
        delete head[i];
    }
    putchar(\n);
    return 0;
}

谢谢阅读。

「模板」 割点

标签:add   block   www.   argv   org   void   ble   ges   head   

原文地址:https://www.cnblogs.com/Capella/p/9042379.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!