zoukankan      html  css  js  c++  java
  • Codeforces 294E Shaass the Great

    树形DP。由于n只有5000,可以直接枚举边。

    枚举边,将树分成两个子树,然后从每个子树中选出一个点分别为u,v,那么答案就是:

    子树1中任意两点距离总和+子树2中任意两点距离总和+子树1中任意一点到u的距离和*子树2的节点个数+子树2中任意一点到v的距离和*子树1的节点个数+子树1的节点个数*子树2的节点个数*当前枚举边的权值。

    当枚举的边一定时,那么要选取的点就是子树中到所有点的距离总和最小的点。对树进行dfs,同时记录子树的节点个数,所有孩子节点到当前根节点的距离总和,以及当前子树中任意两点距离和。然后在进行dfs求解到该子树中所有点距离和最小的点。

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <vector>
     4 #include <algorithm>
     5 using namespace std;
     6 typedef long long LL;
     7 typedef pair <int, int> pii;
     8 #define maxn 5005
     9 #define INF 0x3f3f3f3f3f3f3f3fll
    10 
    11 int f[maxn], h[maxn], w[maxn];
    12 vector<pii> g[maxn];
    13 int son[maxn];
    14 LL d[maxn], s[maxn];
    15 
    16 void dfs(int v, int rt){
    17     son[v] = 0, d[v] = 0, s[v] = 0;
    18     for(int i = 0; i != g[v].size(); i ++){
    19         int u = g[v][i].first;
    20         if(u==rt) continue;
    21         dfs(u, v);
    22         s[v] += s[u] + d[u]*son[v] + d[v]*son[u] + (LL)son[u] * son[v] * g[v][i].second;
    23         d[v] += d[u] + (LL)son[u] * g[v][i].second;
    24         son[v] += son[u];
    25     }
    26     son[v] ++;
    27     s[v] += d[v];
    28 }
    29 void dfsw(int v, int rt, LL &minn){
    30     minn = min(d[v], minn);
    31     for(int i = 0; i != g[v].size(); i ++){
    32         int u = g[v][i].first;
    33         if(u==rt) continue;
    34         d[u] = d[u] + (d[v] - d[u] - (LL)son[u]*g[v][i].second) + (LL)(son[v] - son[u])*g[v][i].second;
    35         son[u] = son[v];
    36         dfsw(u, v, minn);
    37     }
    38 }
    39 int main(){
    40     //freopen("test.in", "r", stdin);
    41     for(int n; scanf("%d", &n)!=EOF; ){
    42         for(int i = 1; i <= n; i ++){
    43             g[i].clear();
    44         }
    45         for(int i = 1, x, y, z; i < n; i ++){
    46             scanf("%d%d%d", &x, &y, &z);
    47             f[i] = x, h[i] = y, w[i] = z;
    48             g[x].push_back(make_pair(y, z));
    49             g[y].push_back(make_pair(x, z));
    50         }
    51         LL ans = INF, minn = INF, sum = 0;
    52         for(int i = 1; i < n; i ++){
    53             minn = INF;
    54             dfs(f[i], h[i]);
    55             dfsw(f[i], h[i], minn);
    56             sum = 0;
    57             sum = (n - son[f[i]]) * minn + s[f[i]];
    58             minn = INF;
    59             dfs(h[i], f[i]);
    60             dfsw(h[i], f[i], minn);
    61             sum = sum + (n - son[h[i]]) * minn + s[h[i]] + (LL)son[f[i]]*son[h[i]]*w[i];
    62             ans = min(ans, sum);
    63         }
    64         printf("%I64d\n", ans);
    65     }
    66     return 0;
    67 }
    View Code
  • 相关阅读:
    bzoj 1061 单纯形法,或转化网络流(待补)
    bzoj 1007 计算几何,单调栈
    bzoj 1015 并查集,离线
    bzoj 1013 高斯消元
    java类继承HttpServlet类实现Servlet程序出现405错误:HTTP method POST is not supported by this URL
    算法的特性和算法设计的要求
    Java实现自定义异常类
    怎么查看 MySQL 数据文件在当前电脑的存储位置
    数据结构的分类
    JS实现“全选”和"全不选"功能
  • 原文地址:https://www.cnblogs.com/bootstar/p/3209286.html
Copyright © 2011-2022 走看看