模拟赛 妖怪等级考试 题解

妖怪等级考试:

给定一个无向连通图,求是否存在两个点之间存在三条路径,
并要求输出路径。
首先,如果两个节点之间存在多条不相交路径,就一定存在一个环。
所以,这题和找环相关。
只有两个环之间存在相交的边,才说明有解。
如图:

现在关键就是如何找到环。
由于无向图dfs后,只有树边和返祖边,且只有返祖边才会形成环,所以只要对返祖边处理就可以了。
每次将第个\(i\)环上所有边染成\(i\)色,当有一个边被染成两种颜色时,就找到了解。
因为每条边最多被染一次就会出现解,所以染色可以暴力进行。
如图:

输出解时考虑三种情况就可以了。

#include <stdio.h>
int fr[100010],ne[400010];
int v[400010],bs=0,fa[100010];
bool fz[400010];
int hu[400010],fb[100010];
int h2,x[400010],dfn[100010],tm=0;
int sd[100010],jg[100010];
void addb(int a,int b)
{
	x[bs]=a;
	v[bs]=b;
	ne[bs]=fr[a];
	fr[a]=bs;
	hu[bs]=-1;
	bs+=1;
}
int dfs(int u,int f)
{
	sd[u]=sd[f]+1;
	fa[u]=f;
	tm+=1;
	dfn[u]=tm;
	for(int i=fr[u];i!=-1;i=ne[i])
	{
		if(v[i]==f)
			continue;
		if(dfn[v[i]]==0)
		{
			fb[v[i]]=i;
			int t=dfs(v[i],u);
			if(t!=-1)
				return t;
		}
		else if(dfn[v[i]]<dfn[u])
		{
			int t=u;
			while(t!=v[i])
			{
				if(hu[fb[t]]!=-1)
				{
					h2=i;
					return fb[t];
				}
				hu[fb[t]]=i;
				t=fa[t];
			}
		}
	}
	return -1;
}
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		fr[i]=-1;
	for(int i=0;i<m;i++)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		addb(a,b);
		addb(b,a);
	}
	int rt=dfs(1,-1);
	if(rt==-1)
		printf("NO");
	else
	{
		printf("YES\n");
		int t=v[hu[rt]];
		if(sd[v[h2]]>sd[t])
			t=v[h2];
		int z=v[rt],s=0;
		while(1)
		{
			s+=1;
			if(z==t)
				break;
			z=fa[z];
		}
		printf("%d ",s);
		z=v[rt];
		while(1)
		{
			printf("%d ",z);
			if(z==t)
				break;
			z=fa[z];
		}
		printf("\n");
		int a1=v[h2],a2=v[hu[rt]];
		z=t,s=0;
		while(1)
		{
			jg[s]=z;
			s+=1;
			if(z==a1)
				break;
			z=fa[z];
		}
		z=x[h2];
		while(1)
		{
			jg[s]=z;
			s+=1;
			if(z==v[rt])
				break;
			z=fa[z];
		}
		printf("%d ",s);
		for(int i=s-1;i>=0;i--)
			printf("%d ",jg[i]);
		printf("\n");
		z=t,s=0;
		while(1)
		{
			jg[s]=z;
			s+=1;
			if(z==a2)
				break;
			z=fa[z];
		}
		z=x[hu[rt]];
		while(1)
		{
			jg[s]=z;
			s+=1;
			if(z==v[rt])
				break;
			z=fa[z];
		}
		printf("%d ",s);
		for(int i=s-1;i>=0;i--)
			printf("%d ",jg[i]);
	}
	return 0;
}
posted @ 2019-07-25 20:20  lnzwz  阅读(179)  评论(0编辑  收藏  举报