zoukankan      html  css  js  c++  java
  • [洛谷P4178]Tree

    题目大意:给一棵树,问有多少条路径长度小于等于$k$

    题解:点分治

    卡点:

    C++ Code:

    #include <cstdio>
    #include <algorithm>
    #define maxn 40010
    const int inf = 0x3f3f3f3f;
    inline int max(int a, int b) {return a > b ? a : b;}
    
    int head[maxn], cnt;
    struct Edge {
    	int to, nxt, w;
    } e[maxn << 1];
    inline void add(int a, int b, int c) {
    	e[++cnt] = (Edge) {b, head[a], c}; head[a] = cnt;
    	e[++cnt] = (Edge) {a, head[b], c}; head[b] = cnt;
    }
    
    bool vis[maxn];
    namespace Center_of_Gravity {
    	int sz[maxn], __nodenum;
    	int root, MIN;
    	#define n __nodenum
    	void __getroot(int u, int fa) {
    		sz[u] = 1;
    		int MAX = 0;
    		for (int i = head[u]; i; i = e[i].nxt) {
    			int v = e[i].to;
    			if (v != fa && !vis[v]) {
    				__getroot(v, u);
    				sz[u] += sz[v];
    				MAX = max(MAX, sz[v]);
    			}
    		}
    		MAX = max(MAX, n - sz[u]);
    		if (MAX < MIN) MIN = MAX, root = u;
    	}
    	int getroot(int u, int nodenum = 0) {
    		n = nodenum ? nodenum : sz[u];
    		MIN = inf;
    		__getroot(u, 0);
    		return root;
    	}
    	#undef n
    }
    using Center_of_Gravity::getroot;
    
    int n, k, ans;
    int S[maxn], tot;
    void getlist(int u, int fa, int val) {
    	if (val <= k) S[++tot] = val;
    	for (int i = head[u]; i; i = e[i].nxt) {
    		int v = e[i].to;
    		if (v != fa && !vis[v]) getlist(v, u, val + e[i].w);
    	}
    }
    int calc(int u, int val) {
    	tot = 0;
    	getlist(u, 0, val);
    	std::sort(S + 1, S + tot + 1);
    	int l = 1, r = tot, res = 0;
    	while (l <= r) {
    		if (S[l] + S[r] <= k) res += r - l, l++;
    		else r--;
    	}
    	return res;
    }
    void solve(int u) {
    	vis[u] = true;
    	ans += calc(u, 0);
    	for (int i = head[u]; i; i = e[i].nxt) {
    		int v = e[i].to;
    		if (!vis[v]) {
    			ans -= calc(v, e[i].w);
    			solve(getroot(v));
    		}
    	}
    }
    
    int main() {
    	scanf("%d", &n);
    	for (int i = 1, a, b, c; i < n; i++) {
    		scanf("%d%d%d", &a, &b, &c);
    		add(a, b, c);
    	}
    	scanf("%d", &k);
    	solve(getroot(1, n));
    	printf("%d
    ", ans);
    	return 0;
    }
    

      

  • 相关阅读:
    CodeForces 7B
    CodeForces 4D
    离散化
    线段树入门
    洛谷 P3951 小凯的疑惑(赛瓦维斯特定理)
    Codeforces 1295D Same GCDs (欧拉函数)
    Codeforces 1295C Obtain The String (二分)
    Codeforces 1295B Infinite Prefixes
    Codeforces 1295A Display The Number(思维)
    Codeforces 1294F Three Paths on a Tree(树的直径,思维)
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9772619.html
Copyright © 2011-2022 走看看