割点

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

什么推荐生了。

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

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

将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);
}
posted @ 2018-05-23 20:22  Lance1ot  阅读(159)  评论(0编辑  收藏  举报