CodeForces 29 DAnt on the Tree, 超经典 裸dfs(序)
来源:互联网 发布:单片机如何控制12v电机 编辑:程序博客网 时间:2024/05/16 17:13
我都不知道 是不是只要会dfs 就能写这题了,真是醉了。 我还去想着用lca 做,虽然可能解出来,但只要把n变大到10000 就GG。
然后dfs序,感觉自己现在毛皮都没有掌握, 只会套用现成的固定的东西算什么会啊, 思维也被算法的框架给限制住了,这真的是一个很可怕的事情,希望我能够明白,算法毕竟是算法,思维才是最重要的东西。 有了思维,有很多很多的算法来解决你的需求,甚至可以写出很简单的代码完成需求。
学习了这位大牛的代码http://blog.csdn.net/lvshubao1314/article/details/43239901
题意:
给一棵树,然后给你一个排列 : 是所有的叶子节点的排列。 然后问你能否在每条边只走两次的情况下,能否完成树的遍历,并把点的顺序记录下来输出。
我们可以知道每条边走两次(也就是一共有 n-1 条边,每条边走两次 2*n-2 每条边u,v其实只记录一个点v ,但是根节点1 开始要记录一次,所以 容器里面一共应该是 2 * n-1个点),利用这个我们可以直接判断能否遍历
最巧妙的地方是 如何运用dfs。
众所周知dfs ,如果你要记录点,你只能先记录dfs 时间戳最深的点, 除非你进入一个dfs就记录一个,
但是!!! 如果这样会记录很多错误的点,比如从根节点1 到 目标节点 end 有很多其他路径都会走,那么会记录很多其他的点。 所以我们只能先判断是不是能到达目标节点,然后再记录。 这样我们能记录的点就会反向, 从 end……….1 , 那我们怎么办呢?
所以我们干脆 反向dfs ,从end 开始 dfs到1, 这样 反*反=正,我们记录的就是正向的一个顺序了, 自己没想到这一层,感觉我自己根本没有完完全全的掌握dfs。弱啊!
/* _ooOoo_ o8888888o 88" . "88 (| -_- |) O\ = /O ____/`---'\____ .' \\| |// `. / \\||| : |||// \ / _||||| -:- |||||- \ | | \\\ - /// | | | \_| ''\---/'' | | \ .-\__ `-` ___/-. / ___`. .' /--.--\ `. . __ ."" '< `.___\_<|>_/___.' >'"". | | : `- \`.;`\ _ /`;.`/ - ` : | | \ \ `-. \_ __\ /__ _/ .-` / /======`-.____`-.___\_____/___.-`____.-'====== `=---='^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 佛祖保佑 永无BUG*/#include<iostream>#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>#include<stdlib.h>#include<queue>#include<stack>#include<map>#include<vector>#define mem(a) memset(a,0,sizeof(a))#define INF 0x7fffffff //INT_MAX#define inf 0x3f3f3f3f //const double PI = acos(-1.0);const double e = exp(1.0);template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; }bool cmpbig(int a,int b){return a>b;}bool cmpsmall(int a,int b){return a<b;}using namespace std;#pragma comment(linker, "/STACK:1024000000,1024000000")const int MAXN=100005;vector<int> edge[310];vector<int> ans;bool dfs(int root,int u,int pre){ if(u==root){// printf("%d =%d\n",u,root); return 1; } for(int i=0;i<edge[u].size();i++){ int v=edge[u][i]; if(v==pre) continue;// ans.push_back(v); 如果这条路找不到 那你难道还要加进来吗 if(dfs(root,v,u)){ // 如果找到了就停止 ans.push_back(u); // 正因为前面是从叶子走到跟,所以这里记录u return 1; } } return 0;}void init(int n){ for(int i=1;i<=n;i++) edge[i].clear(); ans.clear();}void addedge(int a,int b){ edge[a].push_back(b); edge[b].push_back(a);}int f[MAXN];int main(){ // freopen("1.txt","r",stdin); int n,i; scanf("%d",&n); init(n); for( i=1;i<n;i++){ int a,b; scanf("%d %d",&a,&b); addedge(a,b); } int root=1; ans.push_back(1); for(int i=2;i<=n;i++){ if(edge[i].size()==1){ int u; scanf("%d",&u);// dfs(u,root,-1); 起点为1 是正向走,但dfs只能反向记录,即:先记录最深的点 dfs(root,u,-1); // 所以 我们自然要反着来 root=u; } } dfs(root,1,-1); if(ans.size()!=2*n-1) //如果 容器里面的点数超过2*n-1 printf("-1\n"); else{ for(int i=0;i<ans.size();i++){ printf("%d ",ans[i]); } } return 0;}
- CodeForces 29 DAnt on the Tree, 超经典 裸dfs(序)
- Codeforces 29D Ant on the Tree 树的遍历 dfs序
- CodeForces 29D Ant on the Tree
- codeforces 396C On Changing Tree dfs序+BIT
- codeforces 570 D. Tree Requests (dsu on the tree)
- CodeForces 682C - Alyona and the Tree(dfs)
- codeforces 682C Alyona and the Tree(DFS)
- Codeforces 842 C. Ilya And The Tree (dfs)
- Codeforces 842 C. Ilya And The Tree (dfs)
- [HDU 3848]CC On The Tree[dfs]
- CodeForces 29D - Ant on the Tree 暴力LCA
- codeforces 600 E. Lomsat gelral (dsu on the tree)
- codeforces 208 E. Blood Cousins (dsu on the tree)
- 【HDU】4836 The Query on the Tree dfs+线段树
- Codeforces Beta Round #29 (Div. 2, Codeforces format)-D. Ant on the Tree
- CF-29D - Ant on the Tree(DFS+路径保存回扫)
- CodeForces 384E Propagating tree (dfs序)
- [主席树维护HASH && SET维护DFS序] Codechef. Walks on the binary tree
- 在项目中使用wheelPicker控件
- Android_UI_葵花宝典
- 各位有什么超实用的生活小窍门呢?
- windows下python第三方库的安装
- idea快捷键大全
- CodeForces 29 DAnt on the Tree, 超经典 裸dfs(序)
- 朴素贝叶斯与文本分类
- 【机器学习】程序员初学机器学习的四种方式
- [Ubuntu]How to login with root
- 让popupwindow显示在view的上方并与该view水平居中对齐
- APP创业西游记:做到这五点,再谈取真经
- P-N学习
- Android string.xml文件中整型和string型代替以及特殊转义符
- Android开源项目分类汇总