zoukankan      html  css  js  c++  java
  • [CF468D] Tree

    Little X has a tree consisting of n nodes (they are numbered from 1 to n). Each edge of the tree has a positive length. Let's define the distance between two nodes v and u (we'll denote it d(v, u)) as the sum of the lengths of edges in the shortest path between v and u.

    A permutation p is a sequence of n distinct integers p1, p2, ..., pn (1 ≤ pi ≤ n). Little X wants to find a permutation p such that sum is maximal possible. If there are multiple optimal permutations, he wants to find the lexicographically smallest one. Help him with the task!

    Input

    The first line contains an integer n (1 ≤ n ≤ 105).

    Each of the next n - 1 lines contains three space separated integers ui,  vi, wi (1 ≤  ui,  vi ≤  n; 1 ≤  wi ≤  105), denoting an edge between nodes ui and vi with length equal to wi.

    It is guaranteed that these edges form a tree.

    Output

    In the first line print the maximum possible value of the described sum. In the second line print n integers, representing the lexicographically smallest permutation.

    Examples
    Input
    Copy
    2
    1 2 3
    Output
    Copy
    6
    2 1
    Input
    Copy
    5
    1 2 2
    1 3 3
    2 4 4
    2 5 5
    Output
    Copy
    32
    2 1 4 5 3




    写了一上午,我太辣鸡了。
    dis(i,pi)=(depi+deppi2×deplca(i,pi))=2×depi2×deplca(i,pi)
    前面一定是不变的, 后面我们可以把它降低到0, 我们选择树的重心作为根,可以把后边变成0.
    第一问解决。把一个点看成两个, 一个是入点,一个是出点.
    记为in[x], out[x];要满足子树x可以匹配到答案, 我们必须让 $large in[x] + out[x] <= sum in[i]$

    $in[x]$
    $ f[i, j] = $
    $LARGE f[i, j]=frac{sum_{to}^{ } f[nxt[nxt[i,j],j],to] + f[nxt[nxt[i,j],j],j]}{deg[j]+1} + 1$
    latex炸了不写了




    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    #include <set>
    using namespace std;
    inline int read() {
        int res = 0;char ch=getchar();
        while(!isdigit(ch)) ch=getchar();
        while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48), ch=getchar();
        return res;
    }
    #define reg register
    #define N 100005
    #define ll long long
    
    int n;
    struct edge {
        int nxt, to, val;
    }ed[N*2];int head[N], cnt;
    inline void add(int x, int y, int z) {
        ed[++cnt] = (edge) {head[x], y, z};
        head[x] = cnt;
    }
    ll ans;
    int siz[N], root, mrt = 1e9;
    
    void dfs(int x, int fa) 
    {
        siz[x] = 1;
        int tmp = 0;
        for (reg int i = head[x] ; i ; i = ed[i].nxt)
        {
            int to = ed[i].to;
            if (to == fa) continue;
            dfs(to, x);
            siz[x] += siz[to];
            tmp = max(tmp, siz[to]);
        }
        tmp = max(tmp, n - siz[x]);
        if (tmp < mrt) mrt = tmp, root = x;
    }
    
    void gfs(int x, int fa, ll d) {
        ans += d;
        for (reg int i = head[x] ; i ; i = ed[i].nxt) 
        {
            int to = ed[i].to;
            if (to == fa) continue;
            gfs(to, x, d + ed[i].val);
        }
    }
    
    set <int> all;
    set <int> tr[N];
    set < pair <int, int> > inout;
    #define makp(a, b) make_pair(a, b)
    
    int belong[N], sum[N];
    void ffs(int x, int fa, int bel) {
        belong[x] = bel;
        tr[bel].insert(x);
        siz[x] = 1;
        for (reg int i = head[x] ; i ; i = ed[i].nxt) 
        {
            int to = ed[i].to;
            if (to == fa) continue;
            ffs(to, x, bel);
            siz[x] += siz[to];
        }
    }
    
    inline int Find(int x) 
    {
        set < pair <int, int> > :: iterator it = inout.lower_bound(makp(n - x + 1, 0));
        bool must = 0;
        if (it != inout.end() and (*it).first == n - x + 1 and (*it).second != belong[x])  must = 1;
        if (belong[x]) {
            inout.erase(makp(sum[belong[x]], belong[x]));
            sum[belong[x]]--;
            inout.insert(makp(sum[belong[x]], belong[x]));
        }
        if (must) {
            int k = *tr[(*it).second].begin();
            all.erase(k);
            tr[(*it).second].erase(k);
            if (tr[(*it).second].size()) all.insert(*tr[(*it).second].begin());
            inout.erase(makp(sum[belong[k]], belong[k]));
            inout.insert(makp(--sum[belong[k]], belong[k]));
            return k;        
        } else {
            set <int> :: iterator itt = all.begin();
            if(belong[*itt] == belong[x] and x != root) itt++;
            all.erase(itt);
            int k = *itt;
            if (belong[k]) {
                tr[belong[k]].erase(k);
                if (tr[belong[k]].size()) all.insert(*tr[belong[k]].begin());
                inout.erase(makp(sum[belong[k]], belong[k]));
                inout.insert(makp(--sum[belong[k]], belong[k]));        
            }
            return k;
        }
        return 0;
    }
    
    int main()
    {
        n = read();
        for (reg int i = 1 ; i < n ; i ++) {
            int x = read(), y = read(), z = read();
            add(x, y, z), add(y, x, z);
        }
        
        root = 1;
        dfs(1, 0);
        ans = 0;
        gfs(root, 0, 0);
        printf("%lld
    ", ans * 2);
        all.insert(root);
        
        for (reg int i = head[root] ; i ; i = ed[i].nxt) 
        {
            int to = ed[i].to;
            ffs(to, root, to);
            sum[to] = siz[to] * 2;
            inout.insert(makp(sum[to], to));
            siz[root] += siz[to];
            all.insert(*tr[to].begin());
        }
        
        for (reg int i = 1 ; i <= n ; i ++)
            printf("%d ", Find(i));
        return 0;
    }
    
    
    
     
  • 相关阅读:
    wireshark: no interface can be used for capturing in this system
    git上传者姓名修改
    将照片转成base64时候,使用下面的这个包更加安全一些
    The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
    gson之将对象转化成json字符串的方法
    微信之获取微信的openid(二)详细版
    微信支付之获取openid
    后台返回的Json为null的字段不显示的方法
    如果在使用谷歌的gson的时候,在返回时间类型的数据的时候,
    Caused by: org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): com.qingmu.seller.entity.OrderMaster
  • 原文地址:https://www.cnblogs.com/BriMon/p/9547292.html
Copyright © 2011-2022 走看看