AC了但还是有疑问,关于存储路径的问题
查看原帖
AC了但还是有疑问,关于存储路径的问题
998474
ShaunJulian楼主2024/9/14 15:02

其他的东西我都跟正解没什么区别,就是关于存储路径的思路。我一开始的思路是:经过某个节点,直接加到答案的序列中,搜了半天,假如发现走不通,那就去掉这个记录。感觉这么办也没问题,可是只有20分。以下是我的代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+2;
const int maxm=2e5+2;
int n,m,s,cnt=-1;
vector<int>edge[maxn];
vector<bool>uss[maxn];
int q[maxm],pre;
int idge[maxn],odge[maxn];
int st[maxn];
void dfs(int x)
{
	q[++pre]=x;
	cnt++;
	if(cnt==m)//访问的边的数量达到m,就输出所有经过的点 
	{
		for(int i=1;i<=pre;i++)
		printf("%d ",q[i]);
		exit(0);
	}
	for(int i=st[x];i<edge[x].size();i=max(i+1,st[x]))
	if(!uss[x][i])
	{
		uss[x][i]=1;
		st[x]=i+1;
		dfs(edge[x][i]);
	}
	q[pre--]=0;
	cnt--;
}
int main()
{
	scanf("%d%d",&n,&m);
	int a,b;
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&a,&b);
		odge[a]++;
		idge[b]++;
		edge[a].push_back(b);
		uss[a].push_back(0);
	}
	for(int i=1;i<=n;i++)
	sort(edge[i].begin(),edge[i].end());
	a=b=0;
	for(int i=1;i<=n;i++)
	{
		if(abs(idge[i]-odge[i])>1)
		{
			puts("No");
			return 0;
		}
		if(idge[i]+1==odge[i])
		{
			a++;
			s=i;
			if(a>1)
			{
				puts("No");
				return 0;
			}
		}
		if(idge[i]==odge[i]+1)
		{
			b++;
			if(b>1)
			{
				puts("No");
				return 0;
			}
		}
	}
	if(s==0)
	s=1;
	dfs(s);
	return 0;
}

我自己调试的时候,发现当出现自环的情况时,会出现一些我自己也难以解释清楚的问题。也许是记录不全。比如,在第一个测试点,有900多条边,我输出了上述代码中变量cnt曾经最大的时候的值,发现只有800多。

后来,我模仿题解里面的思路,先不存,搜完了以后再存,核心的dfs代码如下:

stack<int> ans;
void dfs(int x)
{
	for(int i=st[x];i<edge[x].size();i=max(i+1,st[x]))
	if(!uss[x][i])
	{
		uss[x][i]=1;
		st[x]=i+1;
		dfs(edge[x][i]);
		uss[x][i]=0;
	}
	ans.push(x);
}

然后就AC了。 我不明白,这两种存储的方式的区别究竟在哪里?请大佬指教。

2024/9/14 15:02
加载中...