1 条题解
-
0
解题思路:
本题要求根据树的普鲁弗码反推树的结构并以特定格式输出。关键点在于理解普鲁弗码生成规则与逆向恢复逻辑的结合:
Prufer序列性质:
每个数字表示当前移除最小叶结点时的父结点编号-
度与频次的关系:
结点的出度等于其在Prufer序列中出现的次数加一
逆向构建逻辑:
从叶结点出发逐步还原父子关系核心难点
动态维护叶结点集合:
使用优先队列实时管理当前可操作叶结点结构化存储
统计频次与初始化对Prufer序列进行统计:
数组记录各结点出现次数→
C++实现
#include<iostream> #include<stdio.h> #include<queue> #include<string.h> #include<string> #include<sstream> #include<algorithm> #include<vector> using namespace std; int f[55],ans[55]; vector<int> vec[55]; bool cmp(const int &a,const int &b) { return a<b; } void dfs(int x) { printf("("); printf("%d",x); int l=vec[x].size(); sort(vec[x].begin(),vec[x].end(),cmp);//vector排序 for(int i=0;i<l;i++) { printf(" "); dfs(vec[x][i]); } printf(")"); vec[x].clear();//清空vector以防影响下组数据 } int main() { int i,n=0; string line; memset(ans,0,sizeof(ans)); while(getline(cin,line))//输入'EOF'停止 { stringstream ss(line);//用sstream类库读取数据 for(n=0;ss>>f[n];n++)// ans[f[n]]++; n--; priority_queue<int,vector<int>,greater<int> > leafs; for(i=1;i<=n+1;i++) if(!ans[i]) leafs.push(i); for(i=0;i<=n;i++) { int k=leafs.top(); leafs.pop(); vec[f[i]].push_back(k); if(--ans[f[i]]==0) leafs.push(f[i]); } if(n!=-1) dfs(f[n]); else printf("(1)");//输入为0 printf("\n"); memset(ans,0,sizeof(ans)); } }
- 1
信息
- ID
- 1569
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 7
- 已通过
- 1
- 上传者