想一下可以发现随便枚举一条直径做就可以了。

核越长越好。于是枚举核的过程可以做到O(n)

然后就是统计答案。

对于每个核最大偏心距肯定是核上面每个点不走核内的点所能走到的最远点的最值。

而且对于核的两端点,距离最远的点肯定是本条直径的端点。

于是我们可以用树形dp,处理出每个直径上的点不走本直径,所能走到的最远点的距离,记为f[]。

然后核每+1,就把当前点f[]塞到单调队列里面。每-1,就把队头弹出。

总共是O(N)。

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <deque>
const int N = 300 + 9;
struct edge{int next,link,w;}es[N*2];
std::deque<int>q;
int dis[N],d_len,len[N],pre[N],p[N],f[N],max_dis[N],ec,son[N],n,s,ans = 0x7fffffff;
bool mark[N];
inline void addedge(const int x,const int y,const int z)
{
es[++ec].next = son[x];
son[x] = ec;
es[ec].link = y;
es[ec].w = z;
}
inline void Addedge(const int x,const int y,const int z){addedge(x,y,z);addedge(y,x,z);}
int bfs(const int s)
{
memset(dis,0,sizeof dis);
memset(pre,0,sizeof pre);
static std::queue<int>q;
for (q.push(s); !q.empty(); ) {
const int u = q.front(); q.pop();
for (int i = son[u]; i; i = es[i].next) {
const int v = es[i].link;
if (v == s || dis[v]) continue;
dis[v] = dis[u] + es[i].w;
pre[v] = u;
q.push(v);
}
}
int res = 1;
for (int i = 1; i <= n; ++i) if (dis[i] > dis[res]) res = i;
return res;
}
void find_diameter()
{
int t,s;
d_len = dis[t = bfs(s = bfs(1))];
while (t) {
mark[t] = true;
p[++p[0]] = t;
len[p[0]] = dis[t] - dis[pre[t]];
t = pre[t];
}
}
void dp(const int u,const int fa)
{
for (int i = son[u]; i; i = es[i].next) {
if (mark[es[i].link] || es[i].link == fa) continue;
dp(es[i].link,u);
f[u] = std::max(f[es[i].link] + es[i].w,f[u]);
}
}
int calc_dis(const int u)
{
memset(f,0,sizeof f);
dp(u,0);
return f[u];
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("core.in","r",stdin);
freopen("core.out","w",stdout);
#endif
scanf("%d%d",&n,&s);
for (int i = 1,x,y,z; i < n; ++i) {
scanf("%d%d%d",&x,&y,&z);
Addedge(x,y,z);
}
find_diameter();
for (int i = 1; i <= p[0]; ++i) {
max_dis[i] = calc_dis(p[i]);
//printf("%d\n",max_dis[i]);
}
for (int i = 1,head = 1,sum = 0,front_dis = 0,tail_dis = 0; i <= p[0]; ++i) {
sum += len[i - 1];
tail_dis += len[i - 1];
while (sum > s) {
front_dis += len[head];
sum -= len[head++];
}
while (q.size() && q.front() < head) q.pop_front();
while (q.size() && max_dis[q.back()] <= max_dis[i]) q.pop_back();
q.push_back(i);
if (q.size()) ans = std::min(ans,std::max(max_dis[q.front()],std::max(d_len - tail_dis,front_dis)));
}
printf("%d\n",ans);
}

  

noip2007树网的核的更多相关文章

  1. Cogs 97. [NOIP2007] 树网的核 Floyd

    题目: http://cojs.tk/cogs/problem/problem.php?pid=97 97. [NOIP2007] 树网的核 ★☆   输入文件:core.in   输出文件:core ...

  2. [SDOI2011]消防/[NOIP2007] 树网的核

    消防 题目描述 某个国家有n个城市,这n个城市中任意两个都连通且有唯一一条路径,每条连通两个城市的道路的长度为zi(zi<=1000). 这个国家的人对火焰有超越宇宙的热情,所以这个国家最兴旺的 ...

  3. NOIP2007 树网的核 && [BZOJ2282][Sdoi2011]消防

    NOIP2007 树网的核 树的直径的最长性是一个很有用的概念,可能对一些题都帮助. 树的直径给定一棵树,树中每条边都有一个权值,树中两点之间的距离定义为连接两点的路径边权之和.树中最远的两个节点之间 ...

  4. noip2007 树网的核

    P1099 树网的核 112通过 221提交 题目提供者该用户不存在 标签动态规划树形结构2007NOIp提高组 难度提高+/省选- 提交该题 讨论 题解 记录   题目描述 设T=(V, E, W) ...

  5. 洛谷1099 [NOIP2007] 树网的核

    链接https://www.luogu.org/problemnew/show/P1099 题目描述 设T=(V,E,W)是一个无圈且连通的无向图(也称为无根树),每条边到有正整数的权,我们称TTT为 ...

  6. NOIP2007 树网的核 [提高组]

    题目:树网的核 网址:https://www.luogu.com.cn/problem/P1099 题目描述 设 T=(V,E,W)T=(V,E,W) 是一个无圈且连通的无向图(也称为无根树),每条边 ...

  7. BZOJ2282 SDOI2011消防/NOIP2007树网的核(二分答案+树形dp)

    要求最大值最小容易想到二分答案.首先对每个点求出子树中与其最远的距离是多少,二分答案后就可以标记上一些必须在所选择路径中的点,并且这些点是不应存在祖先关系的.那么如果剩下的点数量>=3,显然该答 ...

  8. [BZOJ1999][codevs1167][Noip2007]Core树网的核

    [BZOJ1999][codevs1167][Noip2007]Core树网的核 试题描述 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称T为树网(t ...

  9. BZOJ_1999_[Noip2007]Core树网的核_单调队列+树形DP

    BZOJ_1999_[Noip2007]Core树网的核_单调队列+树形DP Description 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称T ...

随机推荐

  1. 使用JavaScript实现使用鼠标画线的效果

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. Selenium/HtmlUnit设置代理获取JS生成的网页

    通常我们使用Java提供的HttpURLConnection或者Apache的HttpClient获取的网页源代码都是直观可见的,其代码的内容和通过浏览器右键网页->点击查看网页源代码的内容一致 ...

  3. java使用simpleDateFormat格式化日期 时间

    时间日期标识符: yyyy:年 MM:月 dd:日 hh:1~12小时制(1-12) HH:24小时制(0-23) mm:分 ss:秒 S:毫秒 E:星期几 D:一年中的第几天 F:一月中的第几个星期 ...

  4. L - Looking for Taste Gym - 101991L 二进制枚举/思维

    方法一:因为最多是10的六次方,所以可以直接枚举二进制上的每一位来得到最优结果. AC代码: #include<iostream> #include<stack> #inclu ...

  5. 数据库与sql注入的相关知识

    数据库与sql注入的相关知识 sql语句明显是针对数据库的一种操作,既然想通过sql注入的方法来拿取数据那么就要先了解一下如何的去操作数据库,这方面并不需要对数据库有多么的精通但是如果了解掌握了其中的 ...

  6. 到底什么是Upnp?[转载]

    本文出自:http://www.cnblogs.com/nehu/archive/2006/05/13/399342.html 解释一. 准确地说,UPnP(Universal Plug and Pl ...

  7. java版云笔记(五)

    下来是创建笔记本,创建笔记,这个没什么难点和前面是一样的. 创建笔记本 首先点击"+"弹出添加笔记的对话框,然后点击确定按钮创建笔记本. //点击"+"弹出添加 ...

  8. 手游研发CJ抱大腿指南

    文摘要:CJ来了,又是一年一度的游戏圈盛事,随着手游行业的迅速崛起,今年CJ上,手游研发商以及发行商必定成为焦点.由于门槛低.市场热.前景好等因素的影响,国内一下子蹦出一大堆手游研发团队.很幸运(或者 ...

  9. initialization 与 finalization 执行顺序 研究

    看GIF: 第二个GIF: DEMO下载:http://files.cnblogs.com/files/del88/InitOrderDemo.zip

  10. 观察者模式和java委托

    观察者模式与java委托 所谓观察者模式,指的某个状态信息的改变,会影响其他一系列的操作,这时就可以将这些操作抽象化,同时创建一个类统一的管理和执行这些操作.把这些抽象出来的操作称为观察者类,而管理这 ...