斐波那契数列

 题目链接:here

题解:

假设现在有 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[1]=A[2]=1,是不是就是一个斐波那契,也就 是对于一个 n 条边的集合,如果不存在三条边能构成一个三角形,那么最长的边至少为 f[n], 表示斐波那契第 n 项。而题目中 A[i]<1e9,也就是只要 n>50,就必定存在三条边可以构成一 个三角形,所以我们只需要暴力加入两点路径上的边(如果大于 50,直接 Yes),然后对这 些边进行排序,枚举第 i 条边为最长边,贪心判断 A[i]是否小于 A[i-1]+A[i-2]即可

 1 #include <cstdio>
 2 #include <set>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <vector>
 6 #include <algorithm>
 7 using namespace std;
 8 
 9 const int N = 1e5+10;
10 int n;
11 int tot, head[N], to[N<<1], nex[N<<1], len[N<<1]; 
12 int f[N], dis[N], dep[N];
13 
14 void init()
15 {
16     tot = 0;
17     for(int i = 0; i <= n; ++ i)
18     {
19         head[i] = -1;
20     }
21 }
22 
23 void addEdge(int x, int y, int l)
24 {
25     to[tot] = y;
26     len[tot] = l;
27     nex[tot] = head[x];
28     head[x] = tot++;
29 }
30 
31 void dfs(int u, int d)
32 {
33     dep[u] = d;
34     for(int i = head[u]; ~i; i = nex[i])
35     {
36         int v = to[i];
37         if(v == f[u]) continue;
38         dis[v] = len[i];
39         f[v] = u;
40         dfs(v, d+1);
41     }
42 }
43 
44 bool solve(int x, int y)
45 {
46     vector<int> vec;
47     while(vec.size() < 50 && x != y)
48     {
49         if(dep[x] < dep[y])
50         {
51             vec.push_back(dis[y]);
52             y = f[y];
53         }
54         else
55         {
56             vec.push_back(dis[x]);
57             x = f[x];
58         }
59     }
60     if(vec.size()>=50) return true;
61     sort(vec.begin(), vec.end());
62     for(int i = 0; i + 2 < vec.size(); ++ i)
63     {
64         if(vec[i] + vec[i+1] > vec[i+2]) return true;
65     }
66     return false;
67 }
68 
69 int main()
70 {
71     int T;
72     scanf("%d", &T);
73     while(T--)
74     {
75         scanf("%d", &n);
76         init();
77         for(int i = 1; i < n; ++ i)
78         {
79             int x, y, l;
80             scanf("%d%d%d", &x, &y, &l);
81             addEdge(x, y, l);
82             addEdge(y, x, l);
83         }
84         dfs(1, 0);
85         int m;
86         scanf("%d", &m);
87         for(int i = 0; i < m; ++ i)
88         {
89             int x, y;
90             scanf("%d%d", &x, &y);
91             puts(solve(x, y) ? "Yes" : "No");
92         }
93     }
94     return 0;
95 } 
标程
原文地址:https://www.cnblogs.com/yijiull/p/7436680.html