CF 294E Shaass the Great【Tree】

来源:互联网 发布:怎么找淘宝内部优惠券 编辑:程序博客网 时间:2024/06/12 00:59

将树的一条边移掉,然后将这条边重新连接两棵子树,使新树:两两点对的距离之和最小。

枚举删掉的边,对每种情况都计算一下,然后取最小值。

对于每种情况,假设左子树的两两点对和为S1,右子树为S2,子树结点个数分别为C1,C2,两个子树到树根的距离和分别为R1,R2,当前枚举的边的权值为w,则整棵树的代价为:

两棵子树的点对和+经过当前边的点对和

S1 + S2 + (C1 + C2)*w + C1*R2 + C2*R1

一棵树如果确定的话,S1和S2都是确定的,不确定的是R1和R2,因此只需要求出R1和R2的最小值。

f[i] 表示以i为根,其他所有结点到i的代价和。则R = min(f[i]), S = sigma(f[i]) / 2;

f[i]的值很容易通过两边遍历求出(具体看代码)。

#include <cstdio>#include <cstring>#include <vector>#include <algorithm>#include <iostream>using namespace std;typedef pair<int, int> pii;typedef long long ll;#define N 5003const ll inf = 1ll<<60;int n, s[N], size;vector<pii> g[N];ll d[N], ans, f[N], sum, res, s1, s2, r1, r2, c1, c2;void dfs1(int now, int fa) {    int u; ll w;    s[now] = 1; f[now] = 0;    for (int i=0; i<g[now].size(); i++)        if ((u = g[now][i].first) != fa) {            dfs1(u, now);            s[now] += s[u];            w = g[now][i].second;            f[now] += f[u] + s[u]*w;        }}void dfs2(int now, int fa) {    int u; ll w;    sum += f[now], res = min(res, f[now]);    for (int i=0; i<g[now].size(); i++)        if ((u = g[now][i].first) != fa) {            w = g[now][i].second;            f[u] = f[now] + w*(size-2*s[u]);            dfs2(u, now);        }}void work(int now, int fa) {    int u; ll w;    for (int i=0; i<g[now].size(); i++)        if ((u = g[now][i].first) != fa) {            dfs1(u, now); size = c1 = s[u]; sum = 0; res = inf;            dfs2(u, now); s1 = sum/2; r1 = res;            dfs1(now, u); size = c2 = s[now]; sum = 0; res = inf;            dfs2(now, u); s2 = sum/2; r2 = res;            w = g[now][i].second;            ans = min(ans, s1+s2+c1*c2*w+c1*r2+c2*r1);            work(u, now);        }}int main() {    scanf("%d", &n);    for (int i=0; i<=n; i++) g[i].clear();    for (int i=1, a, b, c; i<n; i++) {        scanf("%d%d%d", &a, &b, &c);        g[a].push_back(make_pair(b, c));        g[b].push_back(make_pair(a, c));    }    ans = inf;    work(1, 0);    cout << ans << endl;    return 0;}




原创粉丝点击