Uva 10410 Tree Reconstruction
题目大意是根据输入的dfs,bfs重建一棵树并输出他的节点。
这道题一开始做的时候没什么思路,原先是想的根据dfs,bfs递归求解,但没有想出来。
后来参考网上的思路,找到了这道题解决的关键所在:dfs和bfs得到的序列中有一个共同特点,每一个节点的相邻节点可能是兄弟节点,可能是孩子节点,也可能都不是。问题关键是判断他是什么类型的节点,这样得到的树才唯一。因此解决这道题需要使用一个栈来求解。
根据bfs,我们可以得到节点之间的距离。
如果dfs中两节点相邻,代表他们是兄弟节点或者子节点或者其他。把第一个节点当做根节点,根据bfs序列判断根节点和另一个节点的距离,如果距离为负,代表既不是兄弟节点,也不是子节点;如果距离为正且相邻,代表是兄弟节点;否则是孩子节点。这样对于任何一个新加入的节点,总可以在栈中找到他的根节点。从而计算出结果来。
大体我能理解到这个程度,下边是我的实现代码
1 #include <cstdio> 2 #include <vector> 3 #include <algorithm> 4 #include <stack> 5 using namespace std; 6 const int maxn = 1000 + 10; 7 int main(){ 8 int n; 9 vector<int> g[maxn]; 10 int pos[maxn]; 11 while(~scanf("%d",&n)){ 12 for(int i=1;i<=n;i++){ 13 int x; 14 scanf("%d",&x); 15 g[i].clear(); 16 pos[x] = i; 17 } 18 19 int root; 20 stack<int> sta; 21 scanf("%d",&root); 22 sta.push(root); 23 for(int i=1;i<n;i++){ 24 int x; 25 scanf("%d",&x); 26 while(true){ 27 int u = sta.top(); 28 if(u==root||pos[u]+1 <pos[x]) 29 { 30 g[u].push_back(x); 31 sta.push(x); 32 break; 33 } 34 else{ 35 sta.pop(); 36 } 37 } 38 } 39 for(int i=1;i<=n;i++){ 40 printf("%d:",i); 41 sort(g[i].begin(),g[i].end()); 42 for(int d : g[i]){ 43 printf(" %d",d); 44 } 45 puts(""); 46 } 47 48 } 49 return 0; 50 }
另外,
http://www.cnblogs.com/jerryRey/p/4622927.html
这篇博客加深了我对这题的理解。
前边说到相邻序列的三种关系,这篇博客中加了一种讨论
当两节点相邻,但当前节点小于根节点,就代表当前节点是根节点的子节点,要着重注意的是相邻的条件。
但他说的第四条那个等效问题我还不是很明白。以后再回过头来看看。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库