• [BZOJ1316]树上的询问


    [BZOJ1316]树上的询问

    试题描述

    一棵 (n) 个点的带权有根树,有 (p) 个询问,每次询问树中是否存在一条长度为 (Len) 的路径,如果是,输出 Yes 否输出 No.

    输入

    第一行两个整数 (n, p) 分别表示点的个数和询问的个数. 接下来 (n-1) 行每行三个数 (x, y, c),表示有一条树边 (x ightarrow y),长度为 (c). 接下来 (p) 行每行一个数 (Len),表示询问树中是否存在一条长度为 (Len) 的路径.

    输出

    输出有 (p) 行,YesNo.

    输入示例

    6 4
    1 2 5
    1 3 7
    1 4 1
    3 5 2
    3 6 3
    1
    8
    13
    14
    

    输出示例

    Yes
    Yes
    No
    Yes
    

    数据规模及约定

    (30\%) 的数据,(n le 100)

    (100\%) 的数据,(n le 10000)(p le 100)(长度 le 1000000)

    题解

    裸的 (p) 遍点分治。注意考虑 (Len = 0) 的情况。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <algorithm>
    using namespace std;
    #define rep(i, s, t) for(int i = (s), mi = (t); i <= mi; i++)
    #define dwn(i, s, t) for(int i = (s), mi = (t); i >= mi; i--)
    
    int read() {
    	int x = 0, f = 1; char c = getchar();
    	while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
    	while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
    	return x * f;
    }
    
    #define maxn 10010
    #define maxm 20010
    #define maxl 1000010
    
    int n, m, head[maxn], nxt[maxm], to[maxm], dist[maxm], Len;
    
    void AddEdge(int a, int b, int c) {
    	to[++m] = b; dist[m] = c; nxt[m] = head[a]; head[a] = m;
    	swap(a, b);
    	to[++m] = b; dist[m] = c; nxt[m] = head[a]; head[a] = m;
    	return ;
    }
    
    int root, size, f[maxn], siz[maxn];
    bool vis[maxn];
    void getrt(int u, int fa) {
    	siz[u] = 1; f[u] = 0;
    	for(int e = head[u]; e; e = nxt[e]) if(to[e] != fa && !vis[to[e]]) {
    		getrt(to[e], u);
    		siz[u] += siz[to[e]];
    		f[u] = max(f[u], siz[to[e]]);
    	}
    	f[u] = max(f[u], size - siz[u]);
    	if(f[u] < f[root]) root = u;
    	return ;
    }
    int A[maxn], ca, All[maxn], cnt;
    void dfs(int u, int fa, int dep) {
    	if(dep > Len) return ;
    	A[++ca] = dep;
    	for(int e = head[u]; e; e = nxt[e]) if(to[e] != fa && !vis[to[e]]) dfs(to[e], u, dep + dist[e]);
    	return ;
    }
    bool has[maxl], ans;
    bool solve(int u) {
    	vis[u] = 1;
    	cnt = 0;
    	for(int e = head[u]; e; e = nxt[e]) if(!vis[to[e]]) {
    		ca = 0; dfs(to[e], u, dist[e]);
    		rep(i, 1, ca) if(A[i] == Len) ans = 1;
    		rep(i, 1, ca) if(A[i] <= Len && has[Len-A[i]]) ans = 1;
    		rep(i, 1, ca) if(A[i] <= Len) All[++cnt] = A[i], has[A[i]] = 1;
    	}
    	rep(i, 1, cnt) has[All[i]] = 0;
    	if(ans) return 1;
    	for(int e = head[u]; e; e = nxt[e]) if(!vis[to[e]]) {
    		f[root = 0] = size = siz[to[e]]; getrt(to[e], u);
    		if(solve(root)) return 1;
    	}
    	return 0;
    }
    
    int main() {
    	n = read(); int q = read();
    	rep(i, 1, n - 1) {
    		int a = read(), b = read(), c = read();
    		AddEdge(a, b, c);
    	}
    	while(q--) {
    		Len = read();
    		ans = 0; memset(vis, 0, sizeof(vis));
    		f[root = 0] = size = n; getrt(1, 0);
    		puts(solve(root) || !Len ? "Yes" : "No");
    	}
    	
    	return 0;
    }
    
  • 相关阅读:
    Exp5
    Exp4
    Exp3
    Exp02
    【TPM】tpm搭建基础指南
    20155316 Exp1 PC平台逆向破解(5)M
    个人早期写的一些组件
    关于spring @scope("prorotype") 和 @aspectj 一起用的问题
    ThreadLocal内存泄漏需要注意的
    Spring IoC 容器大概流程
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/8479315.html
Copyright © 2020-2023  润新知