Paint it really, really dark gray
题意 有一棵树 每个结点是粉色或黑色 每经过一个结点 就改变他的颜色
从1开始遍历 打印出一条路径 让所有结点都变成黑色
思路就是 每到达一个结点 就改变它的颜色 打印这个结点
然后看它的叶子结点
如果没有叶子结点 自然就返回了
有叶子结点的话 那么递归遍历 把子树里面的颜色都变成黑
返回的时候 如果该叶子节点是粉色 就可以再一次访问该叶子节点 再返回
其实这是很浪费时间的 但是题目说只要打印出来的路径符合就好 我们自己看一棵树很容易看出子树里面存不存在粉色
但是程序就得递归遍历全看一遍了 或者可以预处理dfs一遍 再输出完美答案dfs一遍
但是好像更浪费时间hhh(我在说什么
还有一个细节 因为递归处理都是先改变这个结点的颜色 再去访问叶子节点 但是刚开始从1出发是不会改变1的颜色的
就得特判一下 如果全部处理完之后 1是黑色 那么原来就是粉色 就可以访问叶子 访问自己 再访问叶子 就可以了
代码如下
#include <cstdio> #include <vector> #include <cstring> #include <algorithm> using namespace std; const int maxn = 2e5 + 10; vector<int> G[maxn]; int color[maxn]; int ans[maxn]; int cnt; inline void fun(int u) { color[u] ^= 1; printf("%d ", u); } void dfs(int u, int fa) { fun(u); for (int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if (v == fa) continue; dfs(v, u); fun(u); if (color[v]) fun(v), fun(u); } if (u == 1 && !color[u]) fun(G[u][0]), fun(u), fun(G[u][0]); } int main() { int n; scanf("%d", &n); for (int i = 1, x; i <= n; i++) { scanf("%d", &x); if (x == -1) color[i] = 1; else color[i] = 0; } for (int i = 1, x, y; i < n; i++) { scanf("%d%d", &x, &y); G[x].push_back(y); G[y].push_back(x); } dfs(1, 0); puts(""); return 0; }View Code