• 洛谷P1099 树网的核


    (Large extbf{Description: } large{给你一个无根树和一个非负整数 ext{s},求直径上的一段长度不超过 ext{s}的路径F,使树上结点到F距离最大值的最小值。(5 leq n leq 300, 0 leq s leq 1000)\})

    (Large extbf{Solution: } large{一道特别经典的题目,解法很多,值得反复推敲。\介绍一种解法。我们可以先 ext{dfs}找出树的直径,并在 ext{dfs}过程中维护 ext{dis}与 ext{fa}。\我们可以在直径上借助尺取法,遍历一遍直径顺便维护 ext{ans}。\注意,当 ext{s}大于直径的时候,我们的最大值就要 ext{dfs}一下,求出其余点到直径上任意一点的距离的最大值即可。})

    (Large extbf{Code: })

    #include <cstdio>
    #include <algorithm>
    #define LL long long
    #define gc() getchar()
    #define rep(i, a, b) for(int i = (a); i <= (b); ++i)
    #define _rep(i, a, b) for(int i = (a); i <= (b); ++i)
    using namespace std;
    const int N = 305;
    const int Inf = 0xfffffff;
    int n, cnt, s, cur, Max, ans = Inf, head[N], vis[N], dis[N], f[N];
    
    struct Edge {
    	int to, next, val;	
    }e[N << 1];
    
    inline int read() {
    	char ch = gc();
    	int ans = 0;
    	while (ch > '9' || ch < '0') ch = gc();
    	while (ch >= '0' && ch <= '9') ans = (ans << 1) + (ans << 3) + ch - '0', ch = gc();
    	return ans;	
    }
    
    inline void add(int x, int y, int w) {
    	e[++cnt].to = y;
    	e[cnt].next = head[x];
    	e[cnt].val = w; 
    	head[x] = cnt;	
    }
    
    inline void dfs1(int x, int fa) {
    	f[x] = fa;
    	for (int i = head[x]; i ; i = e[i].next) {
    		int u = e[i].to;
    		if (u == fa) continue;
    		dis[u] = dis[x] + e[i].val;
    		if (dis[u] > Max) Max = dis[u], cur = u;
    		dfs1(u, x);
    	}
    }
    
    inline void dfs2(int x, int fa) {
    	for (int i = head[x]; i ; i = e[i].next) {
    		int u = e[i].to;
    		if (u == fa) continue;
    		if (!vis[u]) dis[u] = dis[x] + e[i].val, ans = max(ans, dis[u]);
    		dfs2(u, x);
    	}
    }
    
    int main() {
    	n = read(), s = read();
    	int x, y, w;
    	rep(i, 2, n) x = read(), y = read(), w = read(), add(x, y, w), add(y, x, w);
    	dfs1(1, 0);
    	int l = cur;
    	rep(i, 1, n) dis[i] = 0;
    	Max = 0, dfs1(l, 0);
    	int r = cur; 
    	for (int i = r, j = r; i; i = f[i]) {
    		vis[i] = 1;
    		while (dis[j] - dis[i] > s) j = f[j];
    		Max = max(dis[i], dis[r] - dis[j]);
    		ans = min(ans, Max);
    	}
    	rep(i, 1, n) dis[i] = 0;
    	dfs2(r, 0);
    	printf("%d
    ", ans);
    	return 0;
    } 
    
  • 相关阅读:
    JS 原型模式 工厂模式 构造函数的区别
    JS 深入1
    理解DOM的一个例子
    Fuzzing参数
    神经网络相关知识和概念整理
    [转载] 系统、模型和仿真
    frp内网穿透,从外网访问内网资源
    常用软件配置
    141. 环形链表
    501. 二叉搜索树中的众数
  • 原文地址:https://www.cnblogs.com/Miraclys/p/12408766.html
Copyright © 2020-2023  润新知