PTA 7-2 地下迷宫探索

 

 

#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了,或者下面的那个赋值可以删掉,理论上都是可以的。

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值