BZOJ1509 [NOI2003]逃学的小孩 树型DP
题目:
分析:
首先明确我们是要求 min(dist[C][A],dist[C][B])+dist[A][B].
我们把C当成树根,第一我们可以发现min里面取dist[C][A]或者dist[C][B]其实是一个意思(因为可以交换)。
接着可以发现dist[A][B]实际上是这棵树的直径。如果不是,那么答案一定不是最优的。我们可以这样去想:
如果dist[A][B]不是直径,那么一定有dist[C][A']使得比dist[C][A]更优,而且A'一定是直径的一个端点:-)。加号的前面和后面都不是最优的,那么答案也不是最优的。
所以我们可以先处理出树的直径,接着枚举点C使得它到两个端点的距离的最小值最大。
时间复杂度O(n),空间复杂度O(n)。
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
using namespace std; typedef long long ll; struct edge{
ll to,w;
}; const ll maxn = ; ll n,m;
vector <edge> g[maxn];
ll arr[maxn],dep[maxn]; void dfs(int now,ll data){
arr[now] = ;
dep[now] = min(dep[now],data);
for(int i=;i<g[now].size();i++){
if(arr[g[now][i].to]) continue;
dfs(g[now][i].to,g[now][i].w+data);
}
arr[now] = ;
} int get_max(){
dep[] = ;
int maxx = ;
for(int i=;i<=n;i++){
if(dep[maxx] < dep[i]) maxx = i;
}
return maxx;
} void read(){
scanf("%lld%lld",&n,&m);
for(ll i=;i<=m;i++){
ll x,y,c; scanf("%lld%lld%lld",&x,&y,&c);
g[x].push_back((edge){y,c});
g[y].push_back((edge){x,c});
}
} void work(){
memset(dep,/,sizeof(dep));
dfs(,);//get the farthest point in tree
ll ans=,t1 = get_max();
memset(dep,/,sizeof(dep));
dfs(t1,);//another point
ll t2 = get_max();
ans += dep[t2];//zhijing
dfs(t2,);
ll maxx = ;
for(int i=;i<=n;i++)
maxx = max(maxx,dep[i]);
ans += maxx; // farthest dian for zhijing
printf("%lld",ans);
} int main(){
read();
work();
return ;
}
BZOJ1509 [NOI2003]逃学的小孩 树型DP的更多相关文章
- BZOJ 1509 逃学的小孩 - 树型dp
传送门 题目大意: 在一棵树中, 每条边都有一个长度值, 现要求在树中选择 3 个点 X.Y. Z , 满足 X 到 Y 的距离不大于 X 到 Z 的距离, 且 X 到 Y 的距离与 Y 到 Z 的距 ...
- BZOJ1509: [NOI2003]逃学的小孩(树的直径)
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1126 Solved: 567[Submit][Status][Discuss] Description ...
- BZOJ1509: [NOI2003]逃学的小孩 (树形DP)
题意:给一棵树 选三个点A,B,C 求A到B的再从B到C的距离最大值 需要满足AB的距离小于AC的距离 题解:首先树上的最大距离就想到了直径 但是被样例误导了TAT BC两点构成了直径 我一开始以为A ...
- BZOJ1509 NOI2003 逃学的小孩
Description: Input: 第一行是两个整数N(3 N 200000)和M,分别表示居住点总数和街道总数.以下M行,每行给出一条街道的信息.第i+1行包含整数Ui.Vi.Ti(1 ...
- BZOJ 1509: [NOI2003]逃学的小孩( 树形dp )
树形dp求出某个点的最长3条链a,b,c(a>=b>=c), 然后以这个点为交点的最优解一定是a+2b+c.好像还有一种做法是求出树的直径然后乱搞... ----------------- ...
- 【BZOJ1509】[NOI2003]逃学的小孩 直径
[BZOJ1509][NOI2003]逃学的小孩 Description Input 第一行是两个整数N(3 N 200000)和M,分别表示居住点总数和街道总数.以下M行,每行给出一条街道的 ...
- [NOI2003]逃学的小孩(树的直径)
[NOI2003]逃学的小孩 题目描述 Chris家的电话铃响起了,里面传出了Chris的老师焦急的声音:"喂,是Chris的家长吗?你们的孩子又没来上课,不想参加考试了吗?"一听 ...
- POJ3659 Cell Phone Network(树上最小支配集:树型DP)
题目求一棵树的最小支配数. 支配集,即把图的点分成两个集合,所有非支配集内的点都和支配集内的某一点相邻. 听说即使是二分图,最小支配集的求解也是还没多项式算法的.而树上求最小支配集树型DP就OK了. ...
- POJ 3342 - Party at Hali-Bula 树型DP+最优解唯一性判断
好久没写树型dp了...以前都是先找到叶子节点.用队列维护来做的...这次学着vector动态数组+DFS回朔的方法..感觉思路更加的清晰... 关于题目的第一问...能邀请到的最多人数..so ea ...
随机推荐
- Linux终端提示符PS1设置(颜色)
\d :代表日期,格式为weekday month date,例如:"Mon Aug 1"\H :完整的主机名称.例如:我的机器名称为:fc4.linux,则这个名称就是fc4.l ...
- ubuntu永久修改主机名
1.查看主机名 在Ubuntu系统中,快速查看主机名有多种方法:其一,打开一个GNOME终端窗口,在命令提示符中可以看到主机名,主机名通常位于“@”符号后:其二,在终端窗口中输入命令:hostname ...
- jquery对象和javascript对象即DOM对象相互转换
jquery对象和javascript对象即DOM对象相互转换 1. DOM 对象转成 jQuery 对象对于已经是一个 DOM 对象,只需要用 $() 把DOM对象包装起来,就可以获得一个 jQue ...
- ConcurrentHashMap分析
1.ConcurrentHashMap锁分段技术 ConcurrentHashMap使用锁分段技术,首先将数据分成一段一段地存储,然后给每一段数据配一把锁,当一 ...
- 【swupdate文档 三】SWUpdate: 嵌入式系统的软件升级
SWUpdate: 嵌入式系统的软件升级 概述 本项目被认为有助于从存储媒体或网络更新嵌入式系统.但是,它应该主要作为一个框架来考虑,在这个框架中可以方便地向应用程序添加更多的协议或安装程序(在SWU ...
- React 16 源码瞎几把解读 【三 点 一】 把react组件对象弄到dom中去(矛头指向fiber,fiber不解读这个过程也不知道)
一.ReactDOM.render 都干啥了 我们在写react的时候,最后一步肯定是 ReactDOM.render( <div> <Home name="home&qu ...
- JAVA 之 Tomcat知识框架【转】
一.Tomcat服务器(很熟悉) 1.Web开发概述 javaSE: javaEE:13种 javaME: JavaEE规范: 13种技术的总称.Servlet/Jsp JDBC JNDI JTA.. ...
- 对 makefile 中 .DEFAULT 的理解
上例子: all:gao @echo "final".DEFAULT: @echo "In default" 由于 gao 是一个前提条件,但是 makefil ...
- geoserver-manager发布style失败
当参数给定没有错误时,最有可能的原因就是: sld文件格式应该以UTF-8无BOM格式编码(自己生成的sld文件多数情况下是以UTF-8格式编码).
- [ python ] 匿名函数和高阶函数
匿名函数 描述: 关键字 lambda 定义的函数 语法: 函数名 = lambda 参数:返回值 返回值: 函数返回结果值 实例: 一个参数的匿名函数: func = lambda ...