• 【HDU】HDU5664 Lady CA and the graph


    原题链接

    题解

    距离省选只有一周了我居然才开始数据结构康复计划

    这题很简单,就是点分树,然后二分一个值,我们计算有多少条路径大于这个值
    对于一个点分树上的重心,我们可以通过双指针的方法求出它子树里的路径任意搭配大于这个值的方案
    然后同一个子树里重复计算的删掉
    再计算和自己祖先之间的路径

    代码

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define space putchar(' ')
    #define enter putchar('
    ')
    #define eps 1e-10
    #define MAXN 50005
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef unsigned int u32;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;T f = 1;char c = getchar();
        while(c < '0' || c > '9') {
    	if(c == '-') f = -1;
    	c = getchar();
        }
        while(c >= '0' && c <= '9') {
    	res = res * 10 +c - '0';
    	c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) {
    	out(x / 10);
        }
        putchar('0' + x % 10);
    }
    struct node {
        int to,next,val;
    }E[MAXN * 2];
    
    int N,sumE,head[MAXN],rt;
    int64 K;
    
    int dep[MAXN],fa[MAXN][20],d[MAXN],zz[MAXN];
    
    bool vis[MAXN];
    
    vector<int> poi;
    vector<int> dis[2][MAXN];
    int tot;
    void add(int u,int v,int c) {
        E[++sumE].to = v;
        E[sumE].next = head[u];
        E[sumE].val = c;
        head[u] = sumE;
    }
    void dfs(int u) {
        zz[u] = zz[fa[u][0]] + 1;
        for(int i = 1 ; i <= 18 ; ++i) fa[u][i] = fa[fa[u][i - 1]][i - 1];
        for(int i = head[u] ; i ; i = E[i].next) {
    	int v = E[i].to;
    	if(v != fa[u][0]) {
    	    fa[v][0] = u;
    	    dep[v] = dep[u] + E[i].val;
    	    dfs(v);
    	}
        }
    }
    int que[MAXN],ql,qr;
    int Calc_G(int st) {
        static int f[MAXN],siz[MAXN],son[MAXN];
        ql = 1;qr = 0;
        que[++qr] = st;f[st] = 0;siz[st] = 1;son[st] = 0;
        while(ql <= qr) {
    	int u = que[ql++];
    	for(int i = head[u] ; i ; i = E[i].next) {
    	    int v = E[i].to;
    	    if(v != f[u] && !vis[v]) {
    		siz[v] = 1;son[v] = 0;
    		f[v] = u;que[++qr] = v;
    	    }
    	}
        }
        int res = que[qr];
        for(int i = qr ; i >= 1 ; --i) {
    	int u = que[i];
    	if(f[u]) {
    	    siz[f[u]] += siz[u];
    	    son[f[u]] = max(son[f[u]],siz[u]);
    	}
    	son[u] = max(son[u],qr - siz[u]);
    	if(son[u] < son[res]) res = u;
        }
        return res;
    }
    void dfs_for_dis(int u,int f) {
        poi.pb(u);
        for(int i = head[u] ; i ; i = E[i].next) {
    	int v = E[i].to;
    	if(v != f && !vis[v]) {
    	    d[v] = d[u] + E[i].val;
    	    dfs_for_dis(v,u);
    	}
        }
    }
    
    void dfs_divide(int u) {
        int G = Calc_G(u);
        vis[G] = 1;
        for(int i = head[G] ; i ; i = E[i].next) {
    	int v = E[i].to;
    	if(!vis[v]) {
    	    poi.clear();
    	    d[v] = E[i].val;
    	    dfs_for_dis(v,G);
    	    ++tot;
    	    for(int j = 0 ; j < poi.size() ; ++j) {
    		dis[1][tot].pb(d[poi[j]]);
    		dis[0][G].pb(d[poi[j]]);
    	    }
    	}
        }
        for(int i = head[G] ; i ; i = E[i].next) {
    	int v = E[i].to;
    	if(!vis[v]) dfs_divide(v);
        }
    }
    int64 check(int mid) {
        int64 res = 0;
        for(int i = 1 ; i <= N ; ++i) {
    	int l = 0,r = dis[0][i].size() - 1;
    	while(r >= 0) {
    	    while(l < dis[0][i].size() && dis[0][i][r] + dis[0][i][l] < mid) ++l;
    	    if(dis[0][i][r] >= mid) res += 2;
    	    res += dis[0][i].size() - l;
    	    --r;
    	}
    	l = 0,r = dis[1][i].size() - 1;
    	while(r >= 0) {
    	    while(l < dis[1][i].size() && dis[1][i][r] + dis[1][i][l] < mid) ++l;
    	    res -= dis[1][i].size() - l;
    	    --r;
    	}
        }
        res /= 2;
        for(int i = 1 ; i <= N ; ++i) {
    	int t = dep[i] - mid;
    	int u = i;
    	for(int j = 18 ; j >= 0 ; --j) {
    	    if(fa[u][j] && dep[fa[u][j]] > t) {
    		u = fa[u][j];
    	    }
    	}
    	res -= zz[u] - zz[rt];
        }
        return res;
    }
    void Init() {
        read(N);read(rt);read(K);
        memset(head,0,sizeof(head));
        memset(vis,0,sizeof(vis));
        sumE = 0;tot = 0;
        for(int i = 1 ; i <= N ; ++i) {dis[0][i].clear();dis[1][i].clear();}
        
        int u,v,c;
        for(int i = 1 ; i < N ; ++i) {
    	read(u);read(v);read(c);
    	add(u,v,c);add(v,u,c);
        }
        dep[rt] = 0;
        fa[rt][0] = 0;
        dfs(rt);
        dfs_divide(rt);
        for(int i = 1 ; i <= N ; ++i) {
    	sort(dis[0][i].begin(),dis[0][i].end());
    	sort(dis[1][i].begin(),dis[1][i].end());
        }
    }
    void Solve() {
        Init();
        int L = 0,R = 500000001;
        while(L < R) {
    	int mid = (L + R + 1) >> 1;
    	if(check(mid) >= K) L = mid;
    	else R = mid - 1;
        }
        if(R == 0) {puts("NO");return;}
        out(L);enter;
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        int T;
        read(T);
        while(T--) Solve();
    }
    
  • 相关阅读:
    Dart中的类型转换总结:
    【Dart学习】--Dart之数组(List)的相关方法总结
    Navigator的使用:
    001——Angular环境搭建、运行项目、搭建项目
    Dart中的数据类型转换:
    Flutter中的Stack、Align、Positioned的使用
    Flutter设置图片为正方形
    顶部导航TabBar、TabBarView、DefaultTabController
    《慕客网:IOS基础入门之Foundation框架初体验》学习笔记 <二> NSMutableString
    Swift随记
  • 原文地址:https://www.cnblogs.com/ivorysi/p/10638749.html
Copyright © 2020-2023  润新知