北邮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
本题说是树,其实仔细分析完应当使用无向图进行建模,然后对该图进行限制性的深度优先遍历。
[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; }
相关文章推荐
- 北邮OJ-268-进程管理-14网研上机C
- 北邮OJ-107. 字符串操作-11网研上机A
- 北邮OJ-108. 虚数-11网研上机B
- 北邮OJ-90. 字符串转换-13网研上机C
- 北邮OJ 108 虚数
- [置顶] 北邮 oj 107 字符串操作
- 北邮OJ-276. 中位数-14计院上机A
- 北邮OJ-93. 中序遍历序列-13计院上机C
- 北邮OJ-271. 旋转图像-14计院上机(第二套)B
- 北邮OJ上的题目——1557
- 北邮新OJ92
- 北邮新OJ100
- 北邮OJ 1021. 16校赛-Stone Game
- 北邮oj最长连续等差子序列
- 北邮OJ 100 二叉树的层数
- 北邮OJ-277. 内存分配-14计院上机B
- 北邮OJ-94. 最小距离查询-13计院上机D
- 北邮OJ-99. 打印字符串-12网研上机A
- 北邮OJ-104. 912星球的研究生-11计院上机B
- 【北邮OJ】88. 最值问题