zoukankan      html  css  js  c++  java
  • 3124: [Sdoi2013]直径

    3124: [Sdoi2013]直径

    https://www.lydsy.com/JudgeOnline/problem.php?id=3124

    分析:

      所有直径都经过的边,一定都是连续的一段。(画个图,反证一下)

      然后可以求出一条直径后,可以对每个点求出不经过直径到达的最远的距离。

      然后判断一下,找到左边分叉的最后一个,右边分叉的第一个,中间的点就是所有直径都经过的点。

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 
     5 inline int read() {
     6     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
     7     for (;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
     8 }
     9 
    10 const int N = 200100;
    11 
    12 int head[N], q[N], fa[N], nxt[N<<1], to[N<<1], Enum;
    13 LL dis[N], dist[N], val[N<<1], Len = 0, Mx = 0;
    14 int Root, Qd, Zd, tot;
    15 bool vis[N];
    16 
    17 inline void add_edge(int u,int v,int w) {
    18     ++Enum; to[Enum] = v; val[Enum] = w; nxt[Enum] = head[u]; head[u] = Enum;
    19     ++Enum; to[Enum] = u; val[Enum] = w; nxt[Enum] = head[v]; head[v] = Enum;
    20 }
    21 
    22 void dfs1(int u,int pa) {
    23     fa[u] = pa;
    24     if (dis[u] > Len) {
    25         Len = dis[u]; Root = u;
    26     }
    27     for (int i=head[u]; i; i=nxt[i]) {
    28         int v = to[i];
    29         if (v == pa) continue;
    30         dis[v] = dis[u] + val[i];
    31         dfs1(v, u);
    32     }
    33 }
    34 
    35 void dfs2(int u,int pa) {
    36     vis[u] = true;
    37     if (dist[u] > Mx) {
    38         Mx = dist[u]; Root = u;
    39     }
    40     for (int i=head[u]; i; i=nxt[i]) {
    41         int v = to[i];
    42         if (v == pa || vis[v]) continue;
    43         dist[v] = dist[u] + val[i];
    44         dfs2(v, u);
    45     }
    46 }
    47 
    48 int main() {
    49     
    50     int n = read();
    51     for (int i=1; i<n; ++i) {
    52         int u = read(), v = read(), w = read();
    53         add_edge(u, v, w);
    54     }
    55     dfs1(1, 0);
    56     Len = 0; Qd = Root; dis[Qd] = 0;
    57     dfs1(Root, 0);
    58     Zd = Root;
    59     
    60     for (int i=Zd; i; i=fa[i]) q[++tot] = i, vis[i] = true;
    61     
    62     int L = tot, R = 1;
    63     for (int i=tot; i>=1; --i) {
    64         Mx = 0;dfs2(q[i], 0);
    65         if (!Mx) continue;
    66         if (Mx == dis[q[i]]) L = i; // 保证所有直径都经过,左边分叉的最后一个 
    67         if (Len - dis[q[i]] == Mx) {R = i; break;} // 右边分叉的第一个
    68     }
    69     cout << Len << "
    " << L - R;    
    70     return 0;
    71 }
  • 相关阅读:
    Flexbox
    jquery.cropper 裁剪图片上传
    让Sublime Text3支持Less
    css实现图片垂直居中
    手淘适配-flexible
    CSSREM
    vue.js+boostrap最佳实践
    最好用的技术是最基础的
    响应式网页布局
    php基础入门
  • 原文地址:https://www.cnblogs.com/mjtcn/p/9350302.html
Copyright © 2011-2022 走看看