#include<stdio.h>
int mp[1009][1009];
int vis[1009];
int N,M,S;
int cnt = 0;
int flag =0;
void dfs(int s)
{
if (cnt!=0) printf (" ");
cnt=1;
printf ("%d",s);
for (int i = 1;i<=N;i++)
{
if (mp[s][i] && !vis[i])
{
vis[i]=1;
flag++;
dfs(i);
printf (" %d",s);//妙啊 太妙了 写的实在是太好了
}
}
}
int main()//路径中某结点被访问多次什么意思
{
scanf ("%d%d%d",&N,&M,&S);
for (int i = 0;i<M;i++)
{
int a,b;
scanf ("%d%d",&a,&b);
mp[a][b]=1;
mp[b][a]=1;
}
vis[S]=1;
dfs(S);
if (flag != N-1) printf(" 0");//必须是N-1 因为你初始化已经将S设置成1了 标记已访问
return 0;
}
这个方法是用DFS深搜出来的题目,但是本题有好几个点是非常的妙,我认为是非常经典的,对我意义很大的一个题。
原题就是相当于深搜一遍图,把所有遍历的点都输出出来,而且还要把回路也给输出出来,我本来的想法是设计一个数组,每次把深搜的值放进去,然后在最后,正序,倒序输出数组的元素,只能过两个测试点,因为我陷入了一个严重的盲区,就是他中途有可能已经访问过了一个小通路了,然后已经返回了,而我那个数组又只能从头到尾,不可能有这么细节的操作。
后来才知道,忘了一个dfs的相当重要的结论啊,他还会出来的,那你直接在进去之前输出一次,出来之后在输出一次,不就行了,很显然,两次的变量应该是同一个值,这也能保证我刚开始走输出一次,回来的时候我再输出一次的这个要求。DFS的这个性质很好用啊。
起始点如果为1的话,也就是我当初代码的漏洞之处,正确的应该是
1 2 6 4 3 5 3 4 7 8 7 4 6 2 1
然后还有最后一个点,那个开始的S为什么要刚开始设置成1,即已经访问过了。
其实相当于就是提前处理一下那个位置,要不然的话,还可以在每次打印x的下面加上一句
flag【x】= 1;意义是一样的,而且这句话实际上只起到了给S注释的一个作用,后面经过dfs进入的其他数据实际上已经赋值为1了,或者下面的那个赋值可以删掉,理论上都是可以的。