zoukankan      html  css  js  c++  java
  • P3806 【模板】点分治1

    (color{#0066ff}{题目描述})

    给定一棵有n个点的树

    询问树上距离为k的点对是否存在。

    (color{#0066ff}{输入格式})

    n,m 接下来n-1条边a,b,c描述a到b有一条长度为c的路径

    接下来m行每行询问一个K

    (color{#0066ff}{输出格式})

    对于每个K每行输出一个答案,存在输出“AYE”,否则输出”NAY”(不包含引号)

    (color{#0066ff}{输入样例})

    2 1
    1 2 2
    2
    

    (color{#0066ff}{输出样例})

    AYE
    

    (color{#0066ff}{数据范围与提示})

    对于30%的数据n<=100

    对于60%的数据n<=1000,m<=50

    对于100%的数据n<=10000,m<=100,c<=1000,K<=10000000

    (color{#0066ff}{题解})

    每次找重心,删去递归子树

    对于每个子树,dfs出到子树根(重心)的距离

    对于同一子树的,会有重复的路径,那不是答案,但是也统计了,所以在枚举孩子的时候要减回去,这部分答案在递归子树的时候会被统计

    每次把所有的子树的dis扔进数组里

    (O(n^2)收集答案)

    #include<bits/stdc++.h>
    using namespace std;
    #define LL long long
    LL in() {
    	char ch; int x = 0, f = 1;
    	while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
    	for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
    	return x * f;
    }
    struct node {
    	int to, dis;
    	node *nxt;
    	node(int to = 0, int dis = 0, node *nxt = NULL): to(to), dis(dis), nxt(nxt) {}
    	void *operator new (size_t) {
    		static node *S = NULL, *T = NULL;
    		return (S == T) && (T = (S = new node[1024]) + 1024), S++;
    	}
    };
    const int maxn = 2e5 + 10;
    int f[maxn], tmp[maxn], dis[maxn], siz[maxn], can[maxn];
    bool vis[maxn];
    node *head[maxn];
    int n, sum, m, root, num;
    
    void add(int from, int to, int dis) {
    	head[from] = new node(to, dis, head[from]);
    }
    void getdis(int x, int fa, int d) {
    	tmp[++num] = d;
    	dis[x] = d;
    	for(node *i = head[x]; i; i = i->nxt)
    		if(i->to != fa && !vis[i->to]) 
    			getdis(i->to, x, d + i->dis);
    }
    void calc(int x, int d, int flag) {
    	num = 0;
    	dis[x] = d;
    	getdis(x, 0, dis[x]);
    	for(int i = 1; i <= num; i++)
    		for(int j = 1; j <= num; j++)
    			if(i != j)
    				can[tmp[i] + tmp[j]] += flag;
    }
    void getroot(int x, int fa) {
    	siz[x] = 1;
    	f[x] = 0;
    	for(node *i = head[x]; i; i = i->nxt) {
    		if(i->to == fa || vis[i->to]) continue;
    		getroot(i->to, x);
    		siz[x] += siz[i->to];
    		f[x] = std::max(f[x], siz[i->to]);
    	}
    	f[x] = std::max(f[x], sum - siz[x]);
    	if(f[x] < f[root]) root = x;
    }
    
    void work(int x) {
    	calc(x, 0, 1);
    	vis[x] = true;
    	for(node *i = head[x]; i; i = i->nxt) 
    		if(!vis[i->to]) {
    			calc(i->to, i->dis, -1);
    			sum = siz[i->to];
    			root = 0;
    			getroot(i->to, 0);
    			work(root);
    		}
    }
    
    int main() {
    	n = in(), m = in();
    	int x, y, z;
    	for(int i = 1; i <= n - 1; i++) {
    		x = in(), y = in(), z = in();
    		add(x, y, z), add(y, x, z);
    	}
    	f[0] = n, sum = n;
    	getroot(1, 0), work(root);
    	while(m --> 0) printf(can[in()]? "AYE
    " : "NAY
    ");
    	return 0;
    }
    
  • 相关阅读:
    HDU Railroad (记忆化)
    HDU 1227 Fast Food
    HDU 3008 Warcraft
    asp vbscript 检测客户端浏览器和操作系统(也可以易于升级到ASP.NET)
    Csharp 讀取大文本文件數據到DataTable中,大批量插入到數據庫中
    csharp 在万年历中计算显示农历日子出错
    csharp create ICS file extension
    CSS DIV Shadow
    DataTable search keyword
    User select fontface/color/size/backgroundColor设置 字体,颜色,大小,背景色兼容主流浏览器
  • 原文地址:https://www.cnblogs.com/olinr/p/10206208.html
Copyright © 2011-2022 走看看