• 洛谷 [P3629] 巡逻


    树的直径

    树的直径有两种求法
    1.两遍 dfs 法, 便于输出具体方案,但是无法处理负权边
    2.DP 法,代码量少,可以处理负权边

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    using namespace std;
    const int MAXN = 200005;
    int n, k, head[MAXN], nume, fa[MAXN], ans, ma, t, d[MAXN], s;
    bool f[MAXN];
    struct edge {
    	int to, nxt, dis;
    }e[MAXN<<1];
    void adde(int from, int to) {
    	e[++nume].to = to;
    	e[nume].dis = 1;
    	e[nume].nxt = head[from];
    	head[from] = nume;
    }
    void dfs1(int u, int dep) {
    	if(f[u]) return ;
    	f[u] = 1;
    	if(dep > ma && u != 1) {
    		ma = dep;
    		k = u;
    	}
    	for(int i = head[u]; i; i = e[i].nxt) {
    		int v = e[i].to;
    		dfs1(v, dep + e[i].dis);
    	}
    }
    void del(int u) {
    	for(int i = head[u]; i; i = e[i].nxt) {
    		int v = e[i].to;
    		if(v == fa[u]) {
    			e[i].dis = e[((i - 1) ^ 1) + 1].dis = -1;
    			del(v);
    		}
    	}
    }
    void dfs2(int u, int dep) {
    	f[u] = 1;
    	if(dep > ma && u != t) {
    		ma = dep; k = u;
    	}
    
    	for(int i = head[u]; i; i = e[i].nxt) {
    		int v = e[i].to;
    		if(!f[v]) {
    			fa[v] = u;
    			dfs2(v, dep + e[i].dis);
    		}
    	}
    }
    void dp(int u) {
    	f[u] = 1;
    	for(int i = head[u]; i; i = e[i].nxt) {
    		int v = e[i].to;
    		if(!f[v]) {
    			dp(v);
    			ma = max(ma, d[u] + d[v] + e[i].dis);
    			d[u] = max(d[u], d[v] + e[i].dis);
    		}
    	}
    }
    int main() {
    	cin >> n >> s;
    	for(int i = 1; i < n; i++) {
    		int u, v;
    		scanf("%d %d", &u, &v);
    		adde(u, v);
    		adde(v, u);
    	}
    	dfs1(1, 0);
    	ma = 0;t = k; k = 0;
    	memset(f, 0, sizeof(f));
    	dfs2(t, 0);
    	ans += 2 * (n - 1) ;
    	ans -= ma - 1;
    	if(s == 2) {
    		del(k);
    		memset(f, 0, sizeof(f));
    		ma = 0;
    		dp(1);
    		ans -= ma - 1;
    	}
    	cout << ans << endl;
    	return 0;
    }
    
  • 相关阅读:
    C++中volatile及编译器优化
    virtualbox 复制虚拟机提示uuid is exists
    Opencv实现简易播放器
    机器学习 Hidden Markov Models 2
    MFC显示Mat图片
    HDU 1518 Square
    马的遍历问题
    JAVA反射机制
    UNIX基础知识
    开机黑屏 仅仅显示鼠标 电脑黑屏 仅仅有鼠标 移动 [已成功解决]
  • 原文地址:https://www.cnblogs.com/Mr-WolframsMgcBox/p/8670788.html
Copyright © 2020-2023  润新知