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;
    }
    

      

  • 相关阅读:
    Dos命令大全(收藏)
    asp.net读写Cookies
    asp.net文件下载
    使用存储过程分页
    (十)死锁检测算法
    poj1664
    一席话惊醒梦中人
    深入了解scanf()/getchar()和gets()/cin等函数
    小结《malloc与new之区别》
    (六)文件管理
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9772619.html
Copyright © 2011-2022 走看看