lca+斐波那契
来源:互联网 发布:mac pro 2016 编辑:程序博客网 时间:2024/06/10 18:01
点击打开链接
Description
有一棵树,树上有只tmk。他在这棵树上生活了很久,对他的构造了如指掌。所以他在树上从来都是走最短路,不会绕路。他还还特别喜欢三角形,所以当他在树上爬来爬去的时候总会在想,如果把刚才爬过的那几根树枝/树干锯下来,能不能从中选三根出来拼成一个三角形呢?
Input
第一行输入一个T,表示有多少组样例。
对于每组数据:第一行包含一个整数N,表示树上节点的个数(从1到N标号)。
接下来的N-1行包含三个整数a, b, len,表示有一根长度为len的树枝/树干在节点a和节点b之间。
接下来一行包含一个整数M,表示询问数。
接下来M行每行两个整数S, T,表示毛毛虫从S爬行到了T,询问这段路程中的树枝/树干是否能拼成三角形。
Output
对于每组数据,每个询问输出一行,包含"Yes"或“No”,表示是否可以拼成三角形。
题解:
假设现在有 n 条线段,假设 n 条边从小到达排序,如果这 n 条边中没有三条可以构成三角形,那么这 n 条边必须满足关系:A[i] >= A[i-2]+A[i-1],这里的 A[i]表示第 i 条边的大小。假设 A[i]尽量取最小 A[i]=A[i-2]+A[i-1],且 A[0]=A[1]=1,是不是就是一个斐波那契,也就是对于一个 n 条边的集合,如果不存在三条边能构成一个三角形,那么最长的边至少为f[n-1],表示斐波那契第 n-1 项。而题目中 A[i]<1e9,也就是只要 n>50,就必定存在三条边可以构成一个三角形,所以我们只需要暴力加入两点路径上的边(如果大于 50,直接 Yes),然后对这些边进行排序,枚举第 i 条边为最长边,贪心判断 A[i]是否小于 A[i-1]+A[i-2]即可。
#include <cstdio>#include <set>#include <cstring>#include <iostream>#include <vector>#include <algorithm>using namespace std;const int maxn=100005;int head[maxn];int dis[maxn];int dep[maxn];int fa[maxn],ans[maxn];struct Edge{ int v,w,nxt;}edge[2*maxn];int tol,tot;int n,m;void addedge(int u,int v,int w){ edge[tol].v=v; edge[tol].w=w; edge[tol].nxt=head[u]; head[u]=tol++;}void dfs(int u,int d){ dep[u]=d; for(int i=head[u];i!=-1;i=edge[i].nxt){ int v=edge[i].v; if(v==fa[u])continue; fa[v]=u; dis[v]=edge[i].w; dfs(v,d+1); }}bool solve(int u,int v){ tot=0; memset(ans,0,sizeof(ans)); while(tot<=50&&u!=v){ if(dep[u]<dep[v]){ ans[++tot]=dis[v]; v=fa[v]; } else{ ans[++tot]=dis[u]; u=fa[u]; } } if(tot>=50)return true; else { sort(ans+1,ans+1+tot); for(int i=1;i<=tot-2;++i){ if(ans[i]+ans[i+1]>ans[i+2]){ return true; } } } return false;}void init(){ tol=0; memset(head,-1,sizeof(head)); for(int i=0;i<=n;++i) fa[i]=i;}int main(){ int T; scanf("%d", &T); while(T--) { scanf("%d", &n); init(); for(int i = 1; i < n; ++ i) { int x, y, l; scanf("%d%d%d", &x, &y, &l); addedge(x, y, l); addedge(y, x, l); } dfs(1, 0); scanf("%d", &m); for(int i = 0; i < m; ++ i) { int x, y; scanf("%d%d", &x, &y); puts(solve(x, y) ? "Yes" : "No"); } } return 0;}
- lca+斐波那契
- 斐波那契
- 斐波那契
- 斐波那契
- 斐波那契
- 斐波那契
- 斐波那契
- 斐波那契
- 斐波那契
- 【斐波那契】
- 斐波那契
- 斐波那契
- 斐波那契
- 斐波那契
- 斐波那契
- 斐波那契
- 斐波那契
- 斐波那契
- Android中Button文字不能一行显示解决方法
- 排序算法详细Java实现
- oj67. Add Binary
- elasticsearch笔记_多字段搜索(六)
- 第6篇:AngularJS路由去掉url里的#号刷新404($locationProvider.html5Mode(true)刷新404)
- lca+斐波那契
- 巧用array.join()处理动态加载可循环列表
- mark
- SublimeText 快速添加注释
- Linux SELinux
- Discuz!教程之如何删除图片模式自动加载下一页
- LoRa
- 【笔记】JQuery自定义插件实现方式
- C++编程中常遇到的问题