2017年10月31日提高组T3 回宿舍

来源:互联网 发布:3d软件培训 编辑:程序博客网 时间:2024/06/05 17:33

Description


这里写图片描述

Input


这里写图片描述

Output


这里写图片描述

Hint


这里写图片描述

Solution


这道题就比较玄妙啦

设f[i]表示由i走向父亲的期望距离,d[i]为点i的度,那么i可以直接走,可以走到任意一个儿子再走回i再走向父亲。即

f[i]=1d[x]+json[i]f[i]+f[j]+1d[x]

再设g[i]表示由i的父亲走向i的期望距离,那么i的父亲可以直接走,可以走到任意一个非i的儿子再走回i的父亲再走向i,也可以走向爷爷再走回来。即

g[i]=1d[fa[i]]+1+g[i]+g[fa[i]]d[fa[i]]+json[fa[i]]jig[i]+f[j]+1d[fa[i]]

然后就有了一张崭新的图,我们要找一条最长链。但是显然不能用两次bfs,因为从i走向j的期望距离不一定等于j走回i的期望距离
因此类似的,记录f的最长链和次长链,g的最长链和次长链,分类讨论一下就可以

Code


#include <stdio.h>#include <string.h>#include <math.h>#include <iostream>#include <queue>#include <vector>#include <algorithm>#define rep(i, st, ed) for (int i = st; i <= ed; i += 1)#define drp(i, st, ed) for (int i = st; i >= ed; i -= 1)#define erg(i, st) for (int i = ls[st]; i; i = e[i].next)#define fill(x, t) memset(x, t, sizeof(x))#define min(x, y) ((x)<(y)?(x):(y))#define max(x, y) ((x)>(y)?(x):(y))#define ld long double#define db double#define ll long long#define INF 0x3f3f3f3f#define N 202001#define E N << 1 | 1#define L 1001struct edge {int x, y, w, next;} e[E];ll f1[N], f2[N], f3[N], g1[N], g2[N], g3[N], f[N], d[N], g[N];int ls[N], fa[N];int edgeCnt = 1, ans;bool inQueue[N];inline int read() {    int x = 0, v = 1;    char ch = getchar();    for (; ch < '0' || ch > '9'; v *= (ch == '-')?(-1):(1), ch = getchar());    for (; ch <= '9' && ch >= '0'; (x *= 10) += ch - '0', ch = getchar());    return x * v;}inline void addEdge(int x, int y, int w) {    e[++ edgeCnt] = (edge) {x, y, w, ls[x]}; ls[x] = edgeCnt;    d[x] += 1;}inline void dfs1(int now) {    erg(i, now) {        if (e[i].y == fa[now]) {            continue;        }        fa[e[i].y] = now;        dfs1(e[i].y);        f[now] += f[e[i].y];    }    f[now] += d[now];}inline void dfs2(int now) {    ll sum = 0;    erg(i, now) {        if (e[i].y == fa[now]) {            continue;        }        sum += f[e[i].y];    }    erg(i, now) {        if (e[i].y == fa[now]) {            continue;        }        g[e[i].y] = d[now] + g[now] + sum - f[e[i].y];        dfs2(e[i].y);    }}inline void solve(int now) {    erg(i, now) {        if (e[i].y == fa[now]) {            continue;        }        solve(e[i].y);        if (f1[e[i].y] + f[e[i].y] > f1[now]) {            f2[now] = f1[now];            f1[now] = f1[e[i].y] + f[e[i].y];            f3[now] = e[i].y;        } else if (f1[e[i].y] + f[e[i].y] > f2[now]) {            f2[now] = f1[e[i].y] + f[e[i].y];        }        if (g1[e[i].y] + g[e[i].y] > g1[now]) {            g2[now] = g1[now];            g1[now] = g1[e[i].y] + g[e[i].y];            g3[now] = e[i].y;        } else if (g1[e[i].y] + g[e[i].y] > g2[now]) {            g2[now] = g1[e[i].y] + g[e[i].y];        }    }    if (g3[now] == f3[now]) {        ans = max(ans, max(f1[now] + g2[now], f2[now] + g1[now]));    } else {        ans = max(ans, f1[now] + g1[now]);    }}int main(void) {    int n = read();    rep(i, 2, n) {        int x = read();        int y = read();        addEdge(x, y, 1);        addEdge(y, x, 1);    }    fa[1] = 0;    dfs1(1);    dfs2(1);    ans = 0;    solve(1);    std:: cout << ans << ".00000" << std:: endl;    return 0;}
原创粉丝点击