有一个trick的地方:
当路劲数大于等于50左右,在题目要求的区间内:1 ≤ len ≤ 1000000000,一定有满足三角形的情况。具体的可以参考斐波那契数列,最坏的情况就是斐波那契的序列。所以大数据要这样过,在cn>=50左右直接返回Yes.
#include <vector>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <fstream>
#include <stdio.h>
using namespace std;
int f[100010][2],deep[100010];
vector<int> e[100010];
int c[60], cn;
void dfs(int fa,int x,int d)
{
deep[x]=d;
for(int i=0;i<(int)e[x].size();i+=2)
{
int y=e[x][i];
if(y==fa)continue;
f[y][0]=x;
f[y][1]=e[x][i+1];
dfs(x,y,d+1);
}
}
int main()
{
int T,ca=1;
// ifstream fin;
// fin.open("aaa.txt");
// cout<<fin.is_open()<<endl;
// fin>>T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
// fin>>n;
for(int i=1;i<=n;i++)e[i].clear();
for(int i=1;i<n;i++)
{
int a,b,len;
scanf("%d%d%d",&a,&b,&len);
// fin>>a>>b>>len;
e[a].push_back(b);
e[a].push_back(len);
e[b].push_back(a);
e[b].push_back(len);
}
dfs(0,1,0);
f[1][0]=0;
printf("Case #%d:\n", ca++);
int m;
scanf("%d",&m);
// fin>>m;
while(m--)
{
int s,t;
cn=0;
scanf("%d%d",&s,&t);
if(s==1 || t==1)
{
int tmp=(s==1)?t:s;
s=1;
t=tmp;
while(f[t][0]!=0)
{
c[cn++]=f[t][1];
t=f[t][0];
if(cn>=50)break;
}
}
else {
while(deep[t]>deep[s])
{
c[cn++]=f[t][1];
t=f[t][0];
if(cn>=50)break;
}
while(deep[s]>deep[t])
{
c[cn++]=f[s][1];
s=f[s][0];
if(cn>=50)break;
}
while(s!=t)
{
c[cn++]=f[s][1];
s=f[s][0];
c[cn++]=f[t][1];
t=f[t][0];
if(cn>=50)break;
}
}
if(cn>=50){printf("Yes\n");continue;}
sort(c,c+cn);
int flag=0;
for(int i=0;i+2<cn;i++)
{
if(c[i]+c[i+1]>c[i+2]){
flag=1;
break;
}
}
if(flag)printf("Yes\n");
else printf("No\n");
}
}
return 0;
}