【bzoj3124】 Sdoi2013—直径
http://www.lydsy.com/JudgeOnline/problem.php?id=3124 (题目链接)
题意
求树的直径以及直径的交。
Solution
我的想法超麻烦,经供参考。。思路还是蛮简单的,就是细节实在是。。。写的我眼泪掉下来。
首先直径很好求,2遍dfs,顺便求出点x儿子节点中的最长链f[x][0],次长链f[x][1]。
考虑如何求直径的交。
对于一条边(u,v),如果它是直径的交,当且仅当所有的直径都经过u,所有的直径都经过v,u的最长链+v的最长链+(u,v)=直径长度。
所以考虑如何求出数组b[x],表示x节点是否被所有直径经过。大家可以自行脑补,我已经不知道自己是怎么AC的了。。
细节
too much。
代码
// bzoj3124
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define inf 2147483640
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std; const int maxn=200010;
struct edge {int to,next,w;}e[maxn<<1];
int head[maxn],son[maxn][2],sum[maxn][2],b[maxn],vis[maxn],cnt,n,tot,rt;
LL f[maxn][3],ans; void link(int u,int v,int w) {
e[++cnt]=(edge){v,head[u],w};head[u]=cnt;
e[++cnt]=(edge){u,head[v],w};head[v]=cnt;
}
void dfs(int x,int fa,LL d) {
if (ans<d) ans=d,rt=x;
for (int i=head[x];i;i=e[i].next) if (e[i].to!=fa) {
dfs(e[i].to,x,d+e[i].w);
if (f[x][0]<f[e[i].to][0]+e[i].w) {
f[x][1]=f[x][0],f[x][0]=f[e[i].to][0]+e[i].w;
son[x][1]=son[x][0],son[x][0]=e[i].to;
sum[x][1]=sum[x][0],sum[x][0]=0;
}
else if (f[x][1]<f[e[i].to][0]+e[i].w) {
son[x][1]=e[i].to;f[x][1]=f[e[i].to][0]+e[i].w;
sum[x][1]=0;
}
if (f[x][0]==f[e[i].to][0]+e[i].w) sum[x][0]++;
if (f[x][1]==f[e[i].to][0]+e[i].w) sum[x][1]++;
}
}
bool Dfs(int x,int fa,LL d) {
f[x][2]=d;
int flag=1,val=b[x],count=0,p;
if (f[x][0]+f[x][1]==ans) flag=0;
val&=flag;
for (int i=head[x];i;i=e[i].next) if (e[i].to!=fa) {
b[e[i].to]=b[x];
if (e[i].to!=son[x][0] && e[i].to!=son[x][1]) b[e[i].to]=val;
else {
if (son[x][0]==e[i].to && sum[x][0]>2) b[e[i].to]=val;
if (son[x][1]==e[i].to && sum[x][1]>1+(f[x][0]==f[x][1])) b[e[i].to]=val;
}
if (f[x][son[x][0]==e[i].to]+f[x][2]==ans) b[e[i].to]=0;
int tmp=Dfs(e[i].to,x,max(f[x][son[x][0]==e[i].to],f[x][2])+e[i].w);
if (!tmp) count++,p=e[i].to;
b[x]&=tmp;flag&=tmp;
}
if (count>1)
for (int i=head[x];i;i=e[i].next) if (e[i].to!=fa && b[e[i].to]) {
b[e[i].to]=0;
Dfs(e[i].to,x,max(f[x][son[x][0]==e[i].to],f[x][2])+e[i].w);
}
if (count==1)
for (int i=head[x];i;i=e[i].next) if (e[i].to!=fa && b[e[i].to] && e[i].to!=p) {
b[e[i].to]=0;
Dfs(e[i].to,x,max(f[x][son[x][0]==e[i].to],f[x][2])+e[i].w);
}
return flag;
}
void dp(int x,int fa) {
for (int i=head[x];i;i=e[i].next) if (e[i].to!=fa) {
dp(e[i].to,x);
if (max(f[x][son[x][0]==e[i].to],f[x][2])+e[i].w+f[e[i].to][0]==ans)
if (b[e[i].to] && b[x])
tot++;
}
}
int main() {
scanf("%d",&n);
for (int u,v,w,i=1;i<n;i++) {
scanf("%d%d%d",&u,&v,&w);
link(u,v,w);
}
dfs(1,0,0);dfs(rt,0,0);
memset(f,0,sizeof(f));
memset(son,0,sizeof(son));
dfs(1,0,0);
printf("%lld\n",ans);
for (int i=1;i<=n;i++) b[i]=1;
Dfs(1,0,0);
dp(1,0);
printf("%d",tot);
return 0;
}
【bzoj3124】 Sdoi2013—直径的更多相关文章
- bzoj3124: [Sdoi2013]直径 树形dp two points
题目链接 bzoj3124: [Sdoi2013]直径 题解 发现所有直径都经过的边 一定在一条直径上,并且是连续的 在一条直径上找这段区间的两个就好了 代码 #include<map> ...
- bzoj千题计划134:bzoj3124: [Sdoi2013]直径
http://www.lydsy.com/JudgeOnline/problem.php?id=3124 第一问: dfs1.dfs2 dfs2中记录dis[i]表示点i距离最长链左端点的距离 第二问 ...
- BZOJ3124 SDOI2013直径
本以为必有高论,结果是个思博题.随便找一条直径,最后答案肯定是这条直径上的连续一段,如果某分支长度等于直径上某端的长度这一端都要被剪掉. #include<iostream> #inclu ...
- [bzoj3124] [Sdoi2013]直径
看了child学长的题解才知道怎么写TAT http://www.cnblogs.com/ctlchild/p/5160272.html 以前不知道直径都是过重心的..代码改着改着就和标程完全一样了Q ...
- 2018.11.05 bzoj3124: [Sdoi2013]直径(树形dp)
传送门 一道sbsbsb树形dpdpdp 第一问直接求树的直径. 考虑第二问问的边肯定在同一条直径上均是连续的. 因此我们将直径记下来. 然后对于直径上的每一个点,dpdpdp出以这个点为根的子树中不 ...
- BZOJ3124 [Sdoi2013]直径 【树的直径】
题目 小Q最近学习了一些图论知识.根据课本,有如下定义.树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度.如果一棵树有N个节点,可以证明其有且仅有N-1 条边. 路径:一棵树上,任意两个节 ...
- BZOJ3124: [Sdoi2013]直径 (树形DP)
题意:给一颗树 第一问求直径 第二问求有多少条边是所有直径都含有的 题解:求直径就不说了 解第二问需要自己摸索出一些性质 任意记录一条直径后 跑这条直径的每一个点 如果以这个点不经过直径能到达最远的 ...
- 【BZOJ3124】[Sdoi2013]直径 树形DP(不用结论)
[BZOJ3124][Sdoi2013]直径 Description 小Q最近学习了一些图论知识.根据课本,有如下定义.树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度.如果一棵树有N个节 ...
- [洛谷P3304] [SDOI2013]直径
洛谷题目链接:[SDOI2013]直径 题目描述 小Q最近学习了一些图论知识.根据课本,有如下定义.树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度.如果一棵树有N个节点,可以证明其有且仅 ...
- 3124: [Sdoi2013]直径
3124: [Sdoi2013]直径 https://www.lydsy.com/JudgeOnline/problem.php?id=3124 分析: 所有直径都经过的边,一定都是连续的一段.(画个 ...
随机推荐
- 【转】Android Studio下加入百度地图的使用 (一)——环境搭建
最近有学 生要做毕业设计,会使用到定位及地图信息的功能,特此研究了一下,供大家参考,百度定位SDK已经更新到了5.0,地图SDK已经更新到了3.5,但是在 AndroidStudio中使用还是存在一些 ...
- Xcode 创建.a和framework静态库(转载)
库介绍 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行.库分静态库和动态库两种. iOS中的静态库有 .a 和 .framework两种形式:动态库有.dylib 和 .framew ...
- Linux命令学习总结:date命令
命令简介: date 根据给定格式显示日期或设置系统日期时间.print or set the system date and time 指令所在路径:/bin/date 命令语法: date [OP ...
- Symantec Backup Exec 2012 Agent For Linux安装
Backup Exec 2012 介绍 Backup Exec 2012 是一种为虚拟和物理环境提供保护的集成产品,能够简化备份和灾难恢复,并提供了无可匹敌的恢复功能.借助于强大的 Symantec ...
- JavaScript(js)的replace问题的解决
我是前端的门外汉,js我用得比较少.今天意外发现js自带的replace “居然”只替换1处,而其它的许多许多语言都是替换全部的. 你可能会说,切,我早就知道.高手请绕道. 你可能会说,用js的正则就 ...
- MYSQL复制
今天我们聊聊复制,复制对于mysql的重要性不言而喻,mysql集群的负载均衡,读写分离和高可用都是基于复制实现.下文主要从4个方面展开,mysql的异步复制,半同步复制和并行复制,最后会简单聊下第三 ...
- 非root用户的SSH免密登录
在网上找到的教程一般是这样说的 cd ~/.ssh/ # 若没有该目录,请先执行一次ssh localhost ssh-keygen -t rsa # 会有提示,都按回车就可以 cat id_rsa. ...
- python2不同版本安装json模块
1.常用json库主要有json-py和simplejson 1) json-py 包含json和minjson,用法一样 Python (#, Jan , ::) [GCC (Red Hat -)] ...
- [已解决]Teamviewer VPN 连接上,但无法ping
用Teamveiwer 可以进行远程控制连接.用了VPN功能后,起先也正常.可以PING和其他网络操作. 后来忽然始终VPN连接上后,无法PING和做其他的网络操作了. 检查缘由是对方TeamView ...
- android 学习中的一些问题记录 主要是概念问题
一些问题记录 应用程序 res 目录常见的目录有哪些,分别放置什么类型的资源? animator/ 和anim/ 放的都是定义动画的XML文件,两个地方的动画类型不同. color/ XML文件:定义 ...