Codeforces 29D Ant on the Tree 树的遍历 dfs序

来源:互联网 发布:数据分析师能力 编辑:程序博客网 时间:2024/06/05 14:22

题目链接:点击打开链接

题意:

给定n个节点的树

1为根

则此时叶子节点已经确定

最后一行给出叶子节点的顺序

目标:

遍历树并输出路径,要求遍历叶子节点时按照给定叶子节点的先后顺序访问。


思路:

给每个节点加一个优先级。

把最后一个叶子节点到父节点的路径上的点优先级改为1

把倒数第二个叶子节点到父节点的路径上的点优先级改为2

如此每个点就有一个优先级,每个访问儿子节点时先访问优先级大的即可


对于无解的判断:得到的欧拉序列不满足输入的叶子节点顺序即是无解。

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <math.h>#include <set>#include <vector>#include <map>using namespace std;#define ll int#define N 310ll n;vector<ll>G[N];int fa[N], du[N];void dfs(int u,int father){fa[u] = father;for(int i = 0; i < G[u].size(); i++) {int v = G[u][i]; if(v==father)continue;dfs(v,u);}}int val[N], Stack[N<<1], top;bool cmp(int a,int b) {return val[a]>val[b];}void work(int u, int father) {Stack[top++] = u;vector<int>son;son.clear();for(int i = 0; i < G[u].size(); i++){int v = G[u][i]; if(v==father)continue;son.push_back(v);}sort(son.begin(), son.end(), cmp);for(int i = 0; i < son.size(); i++) {work(son[i], u);Stack[top++] = u;}}vector<int>input;bool ok(){int u = 0;for(int i = 0; i < top; i++)if(Stack[i]==input[u])u++;return u >= input.size();}int main(){ll i,j,u,v;while(cin>>n){input.clear();memset(du, 0, sizeof du);for(i = 1; i <= n; i++)G[i].clear();for(i = 1; i < n; i++) {scanf("%d %d",&u,&v);G[u].push_back(v);G[v].push_back(u);du[u]++; du[v]++;}int leaf = 0;for(i = 2; i <= n; i++)if(du[i]==1)leaf++;dfs(1,-1);for(i = leaf; i; i--) {scanf("%d",&u);input.push_back(u);while(u!=-1){val[u] = i;u = fa[u];}}top = 0;work(1,-1);if(ok()) {<span style="white-space:pre"></span>for(i = 0; i < top; i++)printf("%d%c",Stack[i],i==top-1?'\n':' ');}else puts("-1");}return 0;}


0 0
原创粉丝点击