zoukankan      html  css  js  c++  java
  • POJ1741(点分治)

    分治的时候SZ感觉是错的……但是貌似第一次找好重心就够了,之后SZ别太离谱就不会T,重心随一随缘就好……

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int maxn = 1e4 + 5;
    int n, k, mx, SZ, ans;
    struct Edge {
    	int to, nxt, cost;
    }e[maxn << 2];
    int head[maxn], tot, size[maxn], root, dis[maxn], vis[maxn];
    int l, r, Q[maxn];
    
    void add(int u, int v, int c) {
    	e[++tot].to = v, e[tot].cost = c, e[tot].nxt = head[u], head[u] = tot;
    }
    
    void GetRoot(int cur, int fa) {
    	int tmp = 0;
    	size[cur] = 1;
    	for (int i = head[cur]; i; i = e[i].nxt) {
    		int son = e[i].to;
    		if (son == fa || vis[son])	continue;
    		GetRoot(son, cur);
    		size[cur] += size[son];
    		tmp = max(tmp, size[son]);
    	}
    	tmp = max(tmp, SZ - size[cur]);
    	if (tmp < mx)	mx = tmp, root = cur;
    }
    
    void GetDis(int cur, int fa) {
    	Q[++r] = dis[cur];
    	for (int i = head[cur]; i; i = e[i].nxt) {
    		int son = e[i].to;
    		if (son == fa || vis[son])	continue;
    		dis[son] = dis[cur] + e[i].cost;
    		GetDis(son, cur);
    	}
    }
    
    int calc(int cur, int val) {
    	l = 1, r = 0;
    	dis[cur] = val;
    	GetDis(cur, 0);
    	sort(Q + 1, Q + 1 + r);
    	int res = 0;
    	while (l < r) {
    		if (Q[l] + Q[r] <= k)	res += r - l, l++;
    		else	r--;
    	}
    	return res;
    }
    
    void divide(int cur) {
    	ans += calc(cur, 0);
    	vis[cur] = 1;
    	for (int i = head[cur]; i; i = e[i].nxt) {
    		int son = e[i].to;
    		if (vis[son])	continue;
    		ans -= calc(son, e[i].cost);
    		mx = 2e9, SZ = size[son];
    		GetRoot(son, 0);
    		divide(root);
    	}
    }
    
    void init() {
    	ans = 0, tot = 0, mx = 2e9, SZ = n;
    	for (int i = 1; i <= n; i++)	head[i] = 0, vis[i] = 0;
    }
    
    int main() {
    	while (scanf("%d %d", &n, &k) == 2 && (n | k)) {
    		init();
    		for (int u, v, cost, i = 1; i < n; i++) {
    			scanf("%d %d %d", &u, &v, &cost);
    			add(u, v, cost), add(v, u, cost);
    		}
    		GetRoot(1, 0);
    		divide(root);
    		printf("%d
    ", ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Android:短信发送
    Android 自制拍照软件
    Android 联系人的读取,查询,添加
    android activity生命周期
    android 让 EditText, TextView自动识别链接
    android Log图文详解(Log.v,Log.d,Log.i,Log.w,Log.e)
    FileOutputStream 读文件的模式
    Android 使用 SharedPreferences 保存和加载软件参数
    使用google的GSON处理JSON
    Android SqlLite数据库的创建、增、删、改、查、使用事务
  • 原文地址:https://www.cnblogs.com/AlphaWA/p/10807258.html
Copyright © 2011-2022 走看看