$Noip2018/Luogu5021$ 赛道修建 二分+树形
$Sol$
一直以为是每个点只能经过一次没想到居然是每条边只能经过一次$....$
首先其实这题$55$分的部分分真的很好写啊,分别是链,数的直径和菊花图,这里就不详细说了.
使得修建的$m$条赛道中长度最小的赛道长度最大有了这句话显然就要考虑考虑二分.现在就是要考虑如何判断了.
任意选择结点作为根建树.注意到一条赛道的组成其实只有两种,一种是一条简单的由浅到深的链,另一种是由深到浅再到深这样的折了一下的链.考虑由深到浅的处理结点.对于每个结点,把子结点上传的链长加上父与子之间的边权加入$mutiset$.首先找到值已经大于等于$mid$的,直接累计答案.然后考虑内部匹配,从小到大扫,找到另一个最小的使得两者相加大于等于$mid$的值,删去这俩结点并且累计答案.最后向父结点上传剩余的链里面最长的就行.
$Code$
#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#include<algorithm>
#define il inline
#define Rg register
#define go(i,a,b) for(Rg int i=a;i<=b;++i)
#define yes(i,a,b) for(Rg int i=a;i>=b;--i)
#define e(i,u) for(Rg int i=b[u];i;i=a[i].nt)
#define mem(a,b) memset(a,b,sizeof(a))
#define v(i) a[i].v
#define w(i) a[i].w
#define ll long long
#define db double
#define IT multiset<ll>::iterator
#define inf 2147483647
using namespace std;
il int read()
{
Rg int x=,y=;char c=getchar();
while(c<''||c>''){if(c=='-')y=-;c=getchar();}
while(c>=''&&c<=''){x=(x<<)+(x<<)+c-'';c=getchar();}
return x*y;
}
const int N=;
int n,m,b[N],ct;
ll d1[N],d2[N],l=inf,r,mid,as;
struct node{int v,w,nt;}a[N*];
il void add(int u,int v,int w){a[++ct]=(node){v,w,b[u]};b[u]=ct;}
il void dfs1(int u,int ft)
{
e(i,u)
{
if(v(i)==ft)continue;
dfs1(v(i),u);
if(d1[v(i)]+w(i)>d1[u]){d2[u]=d1[u];d1[u]=d1[v(i)]+w(i);}
else d2[u]=max(d2[u],d1[v(i)]+w(i));
}
}
il ll dfs(int u,int fa)
{
multiset<ll>q;q.clear();
e(i,u)
{
if(v(i)==fa)continue;
ll val=dfs(v(i),u)+w(i);
if(val>=mid)ct++;
else q.insert(val);
}
ll ret=;
while(q.size())
{
IT i=q.begin();
IT j=q.lower_bound(mid-*i);
if(((i==j)&&q.count(*i)==))j++;
if(j==q.end()){ret=max(ret,*i);q.erase(i);continue;}
ct++;q.erase(q.find(*i));q.erase(q.find(*j));
}
return ret;
}
il bool ck()
{
ct=;dfs(,);
if(ct>=m)return ;return ;
}
int main()
{
n=read(),m=read();
go(i,,n-){Rg int u=read(),v=read(),w=read();add(u,v,w);add(v,u,w);l=min(l,(ll)w);}
dfs1(,);
go(i,,n)r=max(r,d1[i]+d2[i]);
if(m==){printf("%lld\n",r);return ;}
r+=;
while(l<=r)
{
mid=(l+r)>>;
if(ck())as=mid,l=mid+;
else r=mid-;
}
printf("%lld\n",as);
return ;
}
随机推荐
- Oracle函数——COALESCE
COALESCE 含义:COALESCE是一个函数, (expression_1, expression_2, ...,expression_n)依次参考各参数表达式,遇到非null值即停止并返回该值 ...
- huyingsakai的Python学习day1:计算机硬件
1.python是什么?Python是一门编程语言 2.什么是编程语言?(*****)程序员和计算机沟通交流的介质 3.什么是编程?(*****)编程就是程序员想把内心表达的方法用某种计算机语言思维表 ...
- 从DataTable中删除不被控件支持的字段类型
DataTable dt = DB.GetDataTable(sql); //从dt中删除不被控件支持的字段类型 for (int ...
- Layer(Web弹窗)
Layer弹窗的用法: <script src="jQuery的路径"></script> <!-- 你必须先引入jQuery1.8或以上版本 --& ...
- Pytorch学习记录-torchtext和Pytorch的实例( 使用神经网络训练Seq2Seq代码)
Pytorch学习记录-torchtext和Pytorch的实例1 0. PyTorch Seq2Seq项目介绍 1. 使用神经网络训练Seq2Seq 1.1 简介,对论文中公式的解读 1.2 数据预 ...
- SQLSTATE[HY000] [2002] 错误
http://www.thinkphp.cn/topic/36194.html 使用tp框架 3.2.3 ,在windows上跑的时候没有任何问题,但是部署到linux系统和是哪个,就会报这个错,不知 ...
- Activity学习(一):生命周期
一. 认识Activity Activity是Android的四大组件之一,那么它是什么呢?如果简单的理解,可以把它当成应用的一个显示的屏幕. Activity类处于android.app包中,继承体 ...
- ACM学习网站、
转载:http://www.cnblogs.com/zhourongqing/archive/2012/05/24/2516180.html http://61.187.179.132/JudgeOn ...
- torch.nn.LSTM()函数维度详解
123456789101112lstm=nn.LSTM(input_size, hidden_size, num_la ...
- JS中数组声明
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...