• hdu 4868 树分治


    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<map>
    #include<iostream>
    #include<queue>
    using namespace std;
    
    const int M = 60005;
    struct Edge{
        int v, next, w;
    }edge[M << 2], ee[M ];
    map<int, int> mp;
    int E, head[M], hh[M], EE;
    int root, mmax;
    int cc[M], dd[M];
    int cnt[M], mx[M], sz[M];
    int wh[M], dep[M], dis[M];
    int n, m, k;
    int vis[M];
    
    void init(){
        memset(head, -1, sizeof(head));
        memset(hh, -1, sizeof(hh));
        memset(cnt, 0, sizeof(cnt));
        E = EE = 0;
    }
    
    void add_edge(int s, int v, int w){
        edge[E].v = v;
        edge[E].w = w;
        edge[E].next = head[s];
        head[s] = E ++;
    }
    
    void add(int s, int v, int w){
        ee[EE].v = v;
        ee[EE].next = hh[s];
        ee[EE].w = w;
        hh[s] = EE ++;
    }
    
    const int inf = 0x3f3f3f3f;
    int mm ;
    
    void Dijk(){
        priority_queue<pair<int, int> > q;
        for(int i = 0; i < n; i ++){dis[i] = inf;}
        dis[0] = 0;
        memset(vis, 0, sizeof(vis));
        q.push(make_pair(0, 0));
        while(!q.empty()){
            pair<int, int> now = q.top(); q.pop();
            int u = -now.second; int dd = -now.first;
            if(vis[u] == 1) continue;
            vis[u] = 1;
            for(int i = head[u]; i != -1; i = edge[i].next){
                int v = edge[i].v;
                if(dis[v] > dis[u] + edge[i].w){
                    dis[v] = dis[u] + edge[i].w;
                    wh[v] = u;
                    q.push(make_pair(-dis[v], -v));
                }
            }
        }
        for(int i = 1; i < n; i ++) {
            add(wh[i], i, - dis[wh[i]] + dis[i]);
            add(i, wh[i], - dis[wh[i]] + dis[i]);
        }
    }
    
    void dfs1(int u, int fa){
        sz[u] = 1; mx[u] = 0;
        for(int i = hh[u]; i != -1; i = ee[i].next){
            int v = ee[i].v;
            if(v != fa && vis[v] == 0){
                dfs1(v, u);
                mx[u] = max(mx[u], sz[v]);
                sz[u] += sz[v];
            }
        }
    }
    
    void dfs2(int u, int fa, int rt){
        mx[u] = max(mx[u], sz[rt] - sz[u]); if(mx[u] < mmax){
            mmax = mx[u]; root = u;
        }
        for(int i = hh[u]; i != -1; i = ee[i].next){
            int v = ee[i].v;
            if(v != fa && vis[v] == 0){
                dfs2(v, u, rt);
            }
        }
    }
    
    void dfs(int u, int fa, int step, int stop, int w){
        if(w > cc[step]) {
            cc[step] = w;
            dd[step] = 1;
        }else if(w == cc[step]) dd[step] ++;
        if(step == stop) return ;
        for(int i = hh[u]; i != -1; i = ee[i].next){
            int v = ee[i].v;
            if(v == fa || vis[v]) continue;
            dfs(v, u, step+1, stop, w + ee[i].w);
        }
    }
    
    int cal(int u, int tn, int w){
        //printf("%d %d %d
    ", u, sum, w);
        for(int i = 0; i <= tn+1; i ++) {cc[i] = 0; dd[i] = 0;}
        //memset(cnt, 0, sizeof(cnt));
        dfs(u, -1, 1, tn, w);
        int ans = 0;
        if(cc[k-1]) {
            mm = max(mm, cc[k-1]);
            mp[cc[k-1]] += dd[k-1];
        }
        //printf("u = %d
    ", u);
        //for(int i = 1; i <= tn+1; i ++) printf("%d %d %d, %d
    ", cc[i], dd[i], cnt[i], dep[i]);
        for(int i = 1; i < k; i ++){
            if(  cc[i] == 0) break;
            mp[cc[i] + cnt[k - 1 - i]] += dd[i] * dep[k-1-i];
            mm = max(mm, cc[i] + cnt[k-1-i]);
        }
        return ans;
    }
    
    void update(int tn){
        for(int i = 1; i <= tn; i ++){
            if(cc[i]) {
                if(cnt[i] == cc[i]) dep[i] += dd[i];
                else if(cnt[i] < cc[i]) {
                    cnt[i] = cc[i]; dep[i] = dd[i];
                }
            }
            else break;
        }
    }
    
    
    int ans;
    void solve(int u){
        mmax = M;
        root = u;
        dfs1(u, -1);
        dfs2(u, -1, u);
        vis[root] = 1;
        for(int i = 0; i <= mx[root]+1; i ++) {cnt[i] = 0; dep[i] = 0;}
        for(int i = hh[root]; i != -1; i = ee[i].next){
            int v = ee[i].v;
            if(vis[v]) continue;
            int tmp = cal(v, min(k-1, mx[v] + 1), ee[i].w);
            update(min(k-1, mx[v] + 1));
        }
        for(int i = hh[root]; i != -1; i = ee[i].next){
            int v = ee[i].v;
            if(vis[v] == 0)
            solve(v);
        }
    }
    
    /*
    int pah(int u, int fa, int step){
        int m1, m2;
        m1 = 0; m2 = 0;
        for(int i = hh[u]; i != -1; i = ee[i].next){
            int v = ee[i].v;
            if(v == fa) continue;
            int tmp = pah(v, u, step+1) + ee[i].w;
            if(tmp > m1){
                m2 = m1; m1 = tmp; 
            }else if(tmp > m2) m2 = tmp;
        }
        int ret = m1;
        if(step > m1){
            m2 = m1; m1 = step;
        }else if(step > m2) m2 = step;
        mm = max(mm, m1+m2+1);
        return ret;
    }
    */
    int read(){
        int ans = 0;
        char g;
        while((g = getchar()) == ' ' || g == '
    ') ;
        ans = g - '0';
        while((g = getchar()) != ' ' && g != '
    ') ans = ans * 10 + g - '0';
        return ans;
    }
    int main(){
        int T;
        //freopen("1011.in", "r", stdin);
        scanf("%d", &T);
        //T = read();
        while(T --){
      //      n = read(); m = read(); k = read();
            scanf("%d%d%d", &n, &m, &k);
            int a, b, c;
            init();
            for(int i = 0; i < m; i ++){
    //            a = read(); b = read(); c = read();
                scanf("%d%d%d", &a, &b, &c);
               a --; b --;
                add_edge(a, b, c);
                add_edge(b, a, c);
            }
            Dijk();
            memset(vis, 0, sizeof(vis));
            mm = 0;
            solve(1);
            printf("%d %d
    ", mm, mp[mm]);
        }
        return 0;
    }
    

      

  • 相关阅读:
    计算公司下班时间(娱乐)
    设计模式-观察者模式
    vue 打包后白屏的问题
    HashSet实现原理
    LinkedList实现原理
    ArrayList的实现原理
    HashMap实现原理分析
    深入理解java动态代理机制
    Spring工作原理
    数据库SQL优化大总结之 百万级数据库优化方案
  • 原文地址:https://www.cnblogs.com/acmood/p/4621852.html
Copyright © 2020-2023  润新知