【机试备考】Day24-中序遍历树 | DFS

该博客介绍了如何解决一类图论问题,即给定一棵非二叉树,找到所有可能的中序遍历字符串,并从中找出字典序最小的字符串。通过深度优先搜索(DFS)策略,对每个节点作为根节点进行中序遍历,最终得到最小字典序的字符串。示例展示了输入输出格式和代码实现,涉及数据结构和算法的知识。
摘要由CSDN通过智能技术生成

题目

BUPT 2011 网研 ProblemC(oj)
给一棵树,你可以把其中任意一个节点作为根节点。每个节点都有一个小写字母,中序遍历,得到一个字符串,求所有能得到的字符串的字典序最小串。因为这棵树不一定是二叉树,所以中序遍历时,先中序遍历以节点序号最小的节点为根的子树,然后再遍历根节点,最后根据节点序号从小到大依次中序遍历剩下的
子树。

输入描述

多组数据,以 EOF 结束。
第一行一个数 n(0<n<=100),表示树的节点的个数,节点从 0 开始。
然后一个长度为 n 的串,第 i(0<=i<n)个字符表示节点 i 的字符。
接下来 n-1 行,每行两个数 a,b,(0<=a,b<n),表示 a 和 b 之间有一条无向边。

输出描述

题中要求的最小的字符串

示例

输入

3
bac
0 1
1 2
4
abcd
0 1
0 2
0 3

输出

bac
bacd

HINT

意思就是请枚举所有的点为根,然后中序遍历
最后输出所有结果中字典序最小的
比如说第二组数据
以 0 为根时结果为 bacd
以 1 为根时结果为 cadb
以 2 为根时结果为 badc
以 3 为根时结果为 bacd
所以字典序最小的是 bacd

题解

对于多叉树的中序遍历采用DFS,将各节点依次作为进行中序遍历,找出最小的中序遍历序列

#include <bits/stdc++.h>
using namespace std;
int edge[105][105];//邻接矩阵
int visited[105];
string s,res,tmp;//tmp是每次从一个节点dfs遍历得到的字符串,如果小于result,则代替它
void dfs(int pos,int n)
{
    visited[pos]=1;
    vector<int>neighbor;
    for(int i=0;i<n;i++)
    {
        if(i==pos)
            continue;
        if(!visited[i]&&edge[pos][i])
            neighbor.push_back(i);//未被访问的邻接节点加入neighbor
    }
    if(neighbor.size()>0)
    {
        dfs(neighbor[0],n);//左子树
        tmp+=s[pos];//左子树加入后,加入节点字符
        for(int i=1;i<neighbor.size();i++)//右子树
            dfs(neighbor[i],n);
    }
    else
        tmp+=s[pos];
}
int main()
{
    int n;
    while(cin>>n)
    {
        cin>>s;
        memset(edge,0,sizeof(edge));//注意清空邻接矩阵
        for(int i=0;i<n-1;i++)
        {
            int a,b;
            cin>>a>>b;
            edge[a][b]=1;
            edge[b][a]=1;
        }

        for(int i=0;i<n;i++)
        {
            memset(visited,0,sizeof(visited));//新的根节点,重置visited数组
            tmp="";
            dfs(i,n);
            if(i==0)
                res=tmp;
            else if(tmp<res)
                res=tmp;
        }
        cout<<res<<endl;
    }
}

相关题目

2011 网研 ProblemA 字符串操作
2011 网研 ProblemB 虚数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值