109.中序遍历树(中序dfs)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SDUTyangkun/article/details/88617781

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

HINT

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

以2为根时结果为 badc 
以3为根时结果为 bacd 
所以字典序最小的是bacd

输入格式 
多组数据,以EOF结束。

第一行一个数n(0< n < =100),表示树的节点的个数,节点从0开始。

然后一个长度为n的串,第i(0< = i < n)个字符表示节点i的字符。 
接下来n-1行,每行两个数a,b,(0< = a,b < n),表示a和b之间有一条无向边。

输出格式 
题中要求的最小的字符串

输入样例 

bac 
0 1 
1 2 

abcd 
0 1 
0 2 
0 3 
输出样例 
bac 
bacd
 

#include <bits/stdc++.h>

using namespace std;
const int inf=0x3f3f3f3f;
const int maxn = 110;
int vis[maxn];
int mp[maxn][maxn];
string tmp="";
int n;
char s[maxn];
void dfs(int x)
{
    vis[x] = 1;
    if(tmp.size() == n)//递归出口
        return;
    int i;
    for(i = 0; i<n; i++)//左子树
    {
        if(!vis[i] && mp[x][i])
        {
            dfs(i);
            break;
        }
    }

    tmp+=s[x];//根节点
    //cout<<tmp<<endl;
    for(;i < n; i++)//右子树
    {
        if(!vis[i] && mp[x][i])
        {
            dfs(i);
        }
    }
}
int main()
{
    while(~scanf("%d", &n))
    {
        scanf("%s",s);
        memset(mp,0,sizeof(mp));
        for(int  i = 1; i < n; i++)
        {
            int a, b;
            scanf("%d%d", &a, &b);
            mp[a][b] = mp[b][a] = 1;
        }
        string res = "zzzzzzzzzzzzz";
        for(int i = 0; i < n; i++)
        {
            tmp = "";
            memset(vis, 0, sizeof(vis));
            dfs(i);
            if(res > tmp)
                res = tmp;
          //   cout<<"I am :"<<tmp<<endl;
          //  getchar();

        }
        cout<<res<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/SDUTyangkun/article/details/88617781