# bzoj1758+WC2010

1 篇文章 0 订阅

（n<=50000,边权<=10^7）

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <ctime>
using namespace std;
struct node{int to;int next;double len;
};node bian[400010];
int sum = 0,first[400010],size[400010],leng,lenf,max_weight,l,r;
int weight,q[400010],n,a,b;
double Mina,g[400010],f[400010],c;
bool visit[400010],found;
void inser(int x,int y,double z) {
bian[ ++ sum].to = y;
bian[sum].next = first[x];
bian[sum].len = z;
first[x] = sum;
}
void dfs(int x,int Anc) {
size[x] = 1;
for(int u = first[x];u;u = bian[u].next)
if(!visit[bian[u].to] && bian[u].to != Anc)
{
dfs(bian[u].to,x);
size[x] += size[bian[u].to];
}
return;
}
void bfs(int x,int Anc,int depth,double val) {
if(depth > leng) leng = depth,g[leng] = -1000000000000;
if(val > g[depth]) g[depth] = val;
for(int u = first[x];u;u = bian[u].next)
if(!visit[bian[u].to] && bian[u].to != Anc)
bfs(bian[u].to,x,depth + 1,val + bian[u].len - Mina);
}
void find_weight(int x,int Anc,int F) {
int ret = 0;
int sum = 0;
for(int u = first[x];u;u = bian[u].next)
if(!visit[bian[u].to] && bian[u].to != Anc)
{
find_weight(bian[u].to,x,F);
if(size[bian[u].to] > ret)
ret = size[bian[u].to];
sum += size[bian[u].to];
}
if(size[F] - sum > ret) ret = size[F] - sum;
if(ret < max_weight) weight = x,max_weight = ret;
}
void Div(int x,int Anc) {
dfs(x,Anc);
if(l > size[x]) return ;
max_weight = 10000000;
find_weight(x,Anc,x);
dfs(weight,weight);
for(int i = 0;i <= size[weight];i ++) f[i] = g[i] = -1000000000000;
lenf = 0;
for(int u = first[weight];u;u = bian[u].next)
if(!visit[bian[u].to] && bian[u].to != Anc)
{
leng = 0;
bfs(bian[u].to,weight,1,bian[u].len - Mina);
int head = 1,tail = 0,last = leng;
for(int i = 0;i <= lenf;i ++)
{
while(last + i >= l && last >= 0)
{
while(head <= tail && g[last] > g[q[tail]]) tail --;
q[ ++ tail] = last;
last --;
}
if(head <= tail && g[q[head]] + f[i] > 0) { found = true;return ;}
}
lenf = max(lenf,leng);
for(int i = 0;i <= leng;i ++)
if(g[i] > f[i])
f[i] = g[i];
}
visit[weight] = true;
for(int u = first[weight];u;u = bian[u].next)
if(!visit[bian[u].to] && bian[u].to != Anc && found == false)
Div(bian[u].to,weight);
}
bool check(double x) {
memset(visit,false,sizeof(visit));
Mina = x;
found = false;
Div(1,0);
return found;
}
int main() {
scanf("%d",&n);
scanf("%d%d",&l,&r);
for(int i = 1;i < n;i ++)
{
scanf("%d%d",&a,&b);
scanf("%lf",&c);
inser(a,b,c);
inser(b,a,c);
}
double head = 0,tail = 1000000.0;
{
double Mid = (head + tail) / 2.0;
else tail = Mid;
}
return 0;
}

• 0
点赞
• 0
收藏
觉得还不错? 一键收藏
• 1
评论
04-26 325
02-25 116
07-02 1200
08-21 529
02-20 754
04-21 348

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、付费专栏及课程。