「模板」 割点

「模板」 割点

<题目链接>


不会点双导致的 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;
}

谢谢阅读。

posted @ 2018-05-15 18:19  Capella  阅读(123)  评论(0编辑  收藏  举报

谢谢光临