割点

最近一直在忙一些其他的东西。

什么推荐生了。

也没有时间学什么新知识了。

真好今天趁着推荐生考试之前最后一次(有可能是有生之年的最后一次,滑稽)奥赛时间。

将tarjan的割点求法学了吧。

虽然说自己只想放代码。

而且其他大佬都不稀罕学这个,都在争着干什么共同进步啊,什么显示出自己的优越性了。

也不稀罕吵吵些这个,况且我这个蒟蒻没有其他大佬可以现场从0,yy出tarjan的能力。

我还是学了吧。

缩点真是个好东西。

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
struct node
{
    int point;
    int nxt;
};
node line[500000];
int head[100100],tail;
void add(int x,int y)
{
    line[++tail].point=y;
    line[tail].nxt=head[x];
    head[x]=tail;
}
int dfn[100100],low[100100];
bool point[100100];
int ans,tim;
void tarjan(int now,int fa)
{
    low[now]=dfn[now]=++tim;
    int chi=0;
    for(int i=head[now];i;i=line[i].nxt)
    {
        if(dfn[line[i].point])
            low[now]=min(low[now],dfn[line[i].point]);//切记,一定是dfn
        else
        {
            chi+=1;
            tarjan(line[i].point,now);
            low[now]=min(low[now],low[line[i].point]);
            if((fa==-1&&chi>1)||(fa!=-1&&low[line[i].point]==dfn[now]))//根节点是要特判的。
            {
                if(!point[now])
                    ans+=1;
                point[now]=true;//标记
            }
        }
    }
    return ;
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    int a,b;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&a,&b);
        add(a,b);
        add(b,a);
    }
    for(int i=1;i<=n;i++)
        if(!dfn[i])
            tarjan(i,-1);
    printf("%d\n",ans);
    for(int i=1;i<=n;i++)
        if(point[i])    
            printf("%d ",i);
}

猜你喜欢

转载自www.cnblogs.com/Lance1ot/p/9079136.html