[Sdoi2013]直径

时间限制: 1 Sec  内存限制: 256 MB

题目描述

小Q最近学习了一些图论知识。根据课本,有如下定义。树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度。如果一棵树有N个节点,可以证明其有且仅有N-1 条边。 路径:一棵树上,任意两个节点之间最多有一条简单路径。我们用 dis(a,b)
表示点a和点b的路径上各边长度之和。称dis(a,b)为a、b两个节点间的距离。  
 直径:一棵树上,最长的路径为树的直径。树的直径可能不是唯一的。 
现在小Q想知道,对于给定的一棵树,其直径的长度是多少,以及有多少条边满足所有的直径都经过该边。

输入

第一行包含一个整数N,表示节点数。 
接下来N-1行,每行三个整数a, b, c ,表示点 a和点b之间有一条长度为c
的无向边。

输出

共两行。第一行一个整数,表示直径的长度。第二行一个整数,表示被所有
直径经过的边的数量。

样例输入

6
3  1 1000
1  4 10
4  2 100
4  5 50
4  6 100

样例输出

1110
2 【样例说明】
直径共有两条,3 到2的路径和3到6的路径。这两条直径都经过边(3, 1)和边(1, 4)。

提示

对于100%的测试数据:2≤N≤200000,所有点的编号都在1..N的范围内。

Solution:
    自己瞎yy了一下,然后就过了,很懵逼。直径很好求,求完以后直接记录一下直径上的点然后检查一下是否还有等长的就好。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 #define int long long
 7 #define N 200005
 8 #define root 1
 9 int read() {
10     int s=0,f=1;
11     char ch=getchar();
12     for( ; ch<'0'||ch>'9'; f=(ch=='-')?-1:f,ch=getchar()) ;
13     for( ; ch>='0'&&ch<='9'; s=s*10+(ch^48),ch=getchar()) ;
14     return s*f;
15 }
16 int n,tot,r[N],Fa[N],low,high,Dis,deep[N],dis[N],Ans2;
17 struct oo {int fr,to,next,vv;} c[N<<1|1];
18 bool vis[N],Up[N],Down[N];
19 void add(int x,int y,int z) {
20     c[++tot].fr=x;
21     c[tot].to=y;
22     c[tot].vv=z;
23     c[tot].next=r[x];
24     r[x]=tot;
25 }
26 void dfs1(int u,int f,int d) {
27     if(d>Dis) Dis=d,low=u;
28     for(int i=r[u]; ~i; i=c[i].next) if(c[i].to!=f) dfs1(c[i].to,u,d+c[i].vv);
29 }
30 void dfs2(int u,int f) {
31     if(deep[u]>Dis) Dis=deep[u],high=u;
32     for(int i=r[u]; ~i; i=c[i].next) {
33         if(c[i].to!=f) {
34             Fa[c[i].to]=u,dis[c[i].to]=dis[u]+1;
35             deep[c[i].to]=deep[u]+c[i].vv;
36             dfs2(c[i].to,u);
37         }
38     }
39 }
40 void dfs(int u,int f,int d,int &mx) {
41     mx=max(mx,d);
42     for(int i=r[u]; ~i; i=c[i].next) if(c[i].to!=f&&!vis[c[i].to]) dfs(c[i].to,u,d+c[i].vv,mx);
43 }
44 signed main() {
45     n=read();
46     memset(r,0xff,sizeof(r));
47     for(int x,y,z,i=1; i<n; ++i) {
48         x=read(),y=read(),z=read();
49         add(x,y,z),add(y,x,z);
50     } dfs1(root,root,0); Dis=0; dfs2(low,low);
51     for(int i=high; i!=low; i=Fa[i]) vis[i]=true;
52     vis[low]=true;
53     for(int i=high,mx=0; ; i=Fa[i],mx=0) {
54         dfs(i,i,0,mx);
55         if(mx==deep[i]) Up[i]=true;
56         if(mx==Dis-deep[i]) Down[i]=true;
57         if(i==low) break;
58     } int pos1=0,pos2=0;
59     for(int i=high; ; i=Fa[i]) {
60         if(Up[i]&&!pos1) pos1=i;
61         if(Down[i]) pos2=i;
62         if(i==low) break;
63     } Ans2=dis[pos2]-dis[pos1];
64     if(Ans2<0) Ans2=0;
65     printf("%lld\n%lld",Dis,Ans2);
66     return 0;
67 }

转载于:https://www.cnblogs.com/forevergoodboy/p/7780532.html

[Sdoi2013] 直径相关推荐

  1. [SDOI2013]直径 (树的直径,贪心)

    题目链接 Solution 我们直接找到一条直径 \(s\),起点为 \(begin\),终点为 \(end\). 从前往后遍历点 \(u\) ,若子树中最大的距离与 \(dis(u,begin)\) ...

  2. 【洛谷 P3304】[SDOI2013]直径(树的直径)

    题目链接 题意,求一棵树被所有直径经过的边的条数. 这题是我们8.25KS图论的最后一题,当时我果断打了暴力求所有直径然后树上差分统计的方法,好像有点小问题,boom0了. 考完改这题,改了好久,各种 ...

  3. bzoj3124 [Sdoi2013]直径 直径+树形dp

    这个题标签为什么会有网络流.. 首先树的直径求法就是两遍dfs 然后以其中一个为树的根,统计子树到节点的最长距离与次长距离: 符合条件的点一定是最长距离唯一的,且次长距离与到根的距离不相等 注: 1. ...

  4. [SDOI2013]直径

    题目大意: 给你一棵n个结点的带边权的树,求该树直径必经边的个数. 思路: 显然直径必经的所有边的肯定是一个直径上的连续一段. (若超过一段,则出现环,就不是树了) 首先求出原树的任一直径. 预处理出 ...

  5. [51nod] 1766树上的最远点对 树的直径 树剖LCA+ST表静态查询

    题意: 给你一棵带权树,q次查询,每次给出两个区间,[l1,r1][l2,r2][l_1,r_1] [l_2,r_2][l1​,r1​][l2​,r2​]从这两个区间中分别选择两个数字,使得这两个点的 ...

  6. 小A与欧拉路(牛客-树的直径)

    题解: 欧拉路:从图中任意一个点开始到图中任意一个点结束的路径,并且图中每条边只通过恰好一次 问你走完这树上所有的点最短路径是什么. 因为树是没有环的,所以你走到叶子结点的时候需要往回走,也就是再走一 ...

  7. luogu P3306 [SDOI2013] 随机数生成器(BSGS,数列求通项,毒瘤特判)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 发个水题的 题解证明我还在() luogu P3306 [SDOI2013] 随机数生成器 Webli ...

  8. luogu P4408 [NOI2003]逃学的小孩(树的直径)

    整理的算法模板合集: ACM模板 看了半天的题原来没有告诉你三个点的坐标,不然直接跑最短路即可.要求最长的时间,所以我们要自己找到三个点,而在树中最长的路径也就是树的直径.那么本题就可以简化为:在一棵 ...

  9. 模板 - 树上问题(树的直径、动态查询树的直径、树的重心)

    整理的算法模板合集: ACM模板 目录 一.树的直径 树形DP 两次DFS / BFS(找到直径的两个端点) 二.动态修改树的边权并求每个时刻的直径(线段树) 三.树的重心 一.树的直径 树的直径满足 ...

  10. 【树的直径】解题报告: luogu P3629 [APIO2010]巡逻(树的直径,位运算成对变换,思维)

    题目链接:P3629 [APIO2010]巡逻 首先看题,从1号结点开始,全部遍历并回到1号结点会恰好经过所有的边两次,这样总长度为 2∗(n−1)2*(n-1)2∗(n−1). 那么如果建立一条路以 ...

最新文章

  1. Android Studio SDK Manager 解决无法更新问题
  2. ***脚本***普及
  3. 1595 hdu find the longest of the shortest
  4. cout不明确什么意思_劈腿什么意思?原来出轨和劈腿不一样!原来如此!
  5. python数据运算
  6. [转载] Java标识符 数据类型 常量与变量
  7. JavaScript基础知识必知!
  8. 如何快速启动MongoDB服务?
  9. 大团圆结局!苹果高通和解:双方撤销全球所有诉讼
  10. 解决Ubuntun 12.04编译 WARNING: 'automake1.12' is missing on your system
  11. tensorflow2.0:tf.keras.callbacks.EarlyStopping
  12. Python3连接SSH服务器并下载日志文件
  13. 毕业论文查重过关最强最全规律
  14. 如何用计算机对cad的草图,cad文件导入草图大师的方法步骤
  15. 3DMAX制作载具模型导入UE4导致轮子无碰撞解决方案
  16. zer0pts CTF 2022 VishwaCTF 2022
  17. Win10开启卓越性能模式
  18. 解决 注册谷 歌 邮 箱 gmail 手机号无法用于验证
  19. 自我认知测试软件,职业生涯测评系统在线测试
  20. 学计算机颈椎痛,近九成电脑族曾颈椎疼痛,怎么办?

热门文章

  1. java 参数类型转换_java – 如何从通配符类型转换为参数化类型?
  2. FISCO BCOS Failed to connect to nodes: [ ssl hanshake failed:/192.168.64.131:20200]
  3. java并发编程(12)-- 线程池 实际⽣产使⽤哪⼀个线程池 怎么设置
  4. kubernetes视频教程笔记 (10)-资源清单yaml常用字段解释
  5. for ihs linux_在IBM的IHS上编译PHP(redhat 5.5 64位的环境)
  6. C语言第6次上机,C语言第五次上机作业参考答案
  7. 基于SSM的教学质量系统
  8. SpringSession
  9. htc a620d 刷android,续航以及最后的总结_HTC A620d - CNMO
  10. php之通过curl模仿表单提交(get,post)抓取其他页面的内容