割点
最近一直在忙一些其他的东西。
什么推荐生了。
也没有时间学什么新知识了。
真好今天趁着推荐生考试之前最后一次(有可能是有生之年的最后一次,滑稽)奥赛时间。
将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);
}