您的位置:首页 > 其它

北邮OJ-109. 中序遍历树-11网研上机C

2017-03-20 22:02 316 查看
[b]算法分析:[/b]

本题说是树,其实仔细分析完应当使用无向图进行建模,然后对该图进行限制性的深度优先遍历。

[b]Debug记录:(见代码注释)[/b]

没有使用visited标记,出现了两个结点互相访问,死循环

遍历边表的时候应当使用循环尽力搜,知道找到第一个没有visited的结点才是真正的首个子节点,否则是父节点

每调用一次inOrder之前都得重置visited

用引用传参来返回子函数结果很不好!在循环中反复调用的话,一忘记初始化就gg,以后尽量用return。

题目描述

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

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之间有一条无向边。

输出格式

题中要求的最小的字符串

输入样例

3

bac

0 1

1 2

4

abcd

0 1

0 2

0 3

输出样例

bac

bacd

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#define MAXSIZE 300 //最大顶点数
using namespace std;
struct Edge{
int end;
Edge(){
}
Edge(int end){
this->end=end;
}
bool operator<(const Edge e)const{
return end<e.end;
}
};

struct Vex{
char data;
Vex(){
}
Vex(char data){
this->data=data;
}
};
struct Set{ //UnionFindSet 从0开始
int setSize;
vector<Edge> edge[MAXSIZE];
vector<Vex> vex;
bool visited[MAXSIZE];
int initSet(int setSize){
this->setSize=setSize;
for (int i=0;i<setSize;i++){
edge[i].clear();
}
vex.clear();
initVisited();
}
void initVisited(){
for (int i=0;i<setSize;i++){
visited[i]=false;
}
}
void inOrder(string &s,int root){
if (0<=root&&root<vex.size()&&visited[root]==false){//实质上为无向图的DFS,但由于是一棵树,不可能存在回环,
//故只需满足树的遍历入口即指针非空即可,
//必须要判visited!否则会出现父子结点相互回访死循环!/*bug1*/
//traverse
int p=0;
visited[root]=true;
for (p=0;p<edge[root].size();p++){//遍历边表,为了保证不会将其父节点错认为是第一个子节点 /*bug2*/
if (visited[edge[root][p].end]==false){
inOrder(s,edge[root][p].end);
break;
}
}
//visit
s+=vex[root].data;
//traverse
for (;p<edge[root].size();p++){
inOrder(s,edge[root][p].end);
}
}
}
};
int main(){
int n;
char datas[200];
Set set;
int x,y;
while (scanf("%d",&n)!=EOF){
//initiate
set.initSet(n);
//input
scanf("%s",datas);
for (int i=0;datas[i]!='\0';i++){
set.vex.push_back(Vex(datas[i]));
}
for (int i=0;i<n-1;i++){
scanf("%d%d",&x,&y);
set.edge[x].push_back(Edge(y));
set.edge[y].push_back(Edge(x));
}
//sort edges
for (int i=0;i<n;i++){
sort(set.edge[i].begin(),set.edge[i].end());
}
//process
string s1="",s2="";
set.inOrder(s1,0);
for (int i=1;i<n;i++){
//initiate
set.initVisited();/*bug3*/
s2="";/*bug4*/
set.inOrder(s2,i);
if (s2<s1){
s1=s2;
}
}
//output
cout<<s1<<endl;
}
return true;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息