zoukankan      html  css  js  c++  java
  • 2018牛客多校第六场 G.Pikachu

    题意:

      给出一棵n个点的树,每条边有边权。对这个树加边变成一个完全图。新加的边的权值为边上两点在树上的距离。求完全图上任意两点的最大流之和。

    题解:

      一共有C(n,2)个点对。假设当前求s到t之间的最大流,也就是最小割。那么割完之后会是2个连通块,且连通块内部是完全图。

      因为是最小割,所以被割掉的边权和最小。即两个连通块内部的边权和最大。那么就会有一个连通块是孤立点,取s和t中到其余所有点距离小的作为孤立点。

      问题变成了求每个点到其他所有点的距离。

      dfs第一次求每个点到他所有儿子节点的距离,dfs第二次将剩余的距离更新。

      最后排序统计答案。答案会爆ll所以要用类似大数的方法处理一下。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 1e5+10;
    const ll inf = 1e17;
    int t, n, tot, cnt;
    int u, v;
    int num[N];
    int head[N], to[N<<1], nxt[N<<1], w[N<<1];
    ll ans;
    ll d[N];
    void dfs(int u, int fa) {
        num[u] = 1;
        d[u] = 0;
        for(int i = head[u]; ~i; i = nxt[i]) {
            int v = to[i];
            if(v == fa) continue;
            dfs(v, u);
            num[u] += num[v];
            d[u] += d[v]+num[v]*w[i];
        }
    }
    void re_dfs(int u, int fa) {
        for(int i = head[u]; ~i; i = nxt[i]) {
            int v = to[i];
            if(v == fa) continue;
            d[v] = d[u]+(n-2*num[v])*w[i];
            re_dfs(v, u);
        }
    }
    int main() {
        scanf("%d", &t);
        for(int casee = 1; casee <= t; casee++) {
            scanf("%d", &n);
            tot = ans = cnt = 0;
            memset(head, -1, sizeof(int)*(n+2));
            for(int i = 1; i < n; i++) {
                scanf("%d%d", &u, &v);
                to[++tot] = v; nxt[tot] = head[u]; head[u] = tot; scanf("%d", &w[tot]);
                to[++tot] = u; nxt[tot] = head[v]; head[v] = tot; w[tot] = w[tot-1];
            }
            dfs(1, 0);
            re_dfs(1, 0);
            sort(d+1, d+n+1);
            for(int i = 1; i <= n; i++) {
                ans += d[i]*(n-i);
                cnt += ans/inf;
                ans %= inf;
            }
            if(cnt) printf("Case #%d: %d%017lld
    ", casee, cnt, ans);
            else printf("Case #%d: %lld
    ", casee, ans);
        }
    } 
    View Code

      

  • 相关阅读:
    redis05
    redis04
    redis03
    redis02
    C++编程学习(九)this指针&友元函数
    C++编程学习(八)new&delete动态内存分配
    ROS大型工程学习(二) 怎么阅读大型工程
    计算机操作系统学习(一) Linux常用指令(随时更新)
    ROS大型工程学习(一) 必须了解的基本文件
    单片机学习(一) 中断、定时器、优先级的一些理解
  • 原文地址:https://www.cnblogs.com/Pneuis/p/9434426.html
Copyright © 2011-2022 走看看