• 树的直径&


    树的直径

    树上最远两点(叶子结点)的距离。这里推荐dfs求树的直径。

    性质

    • 树上任意点能到的最远点,一定是树的直径的某个端点。

    Cow Marathon

    模板题,让你求距离最远的两个节点的距离,那么就是树的直径。树的直径怎么求,首先随便从一点u开始搜索找到离他最远的点t1,再从该点t1,搜索出离t1最远的点t2,t1跟t2就是树上最远两点。详细证明参考这篇博客传送门
    下面展示一些 内联代码片

    #include <iostream>
    using namespace std;
    const int N = 4e4 + 5;
    struct E {
    	int to, nex, w;
    }e[N << 1];
    int cnt, head[N];
    void Add(int u, int v, int w) {
    	e[++cnt].to = v;
    	e[cnt].w = w;
    	e[cnt].nex = head[u];
    	head[u] = cnt;
    }
    int mxd, mxu, t1, t2; 
    void dfs(int u, int fa, int d) {
    	if(d > mxd) { 
    		mxd = d; //update deep
    		mxu = u; //update id
    	}
    	for(int i = head[u]; i; i = e[i].nex) {
    		int v = e[i].to, w = e[i].w;
    		if(v == fa) continue;
    		dfs(v, u, d + w);
    	}
    }
    void solve() {
    	int n, m, u, v, w;
    	char c;
    	cin >> n >> m;
    	for(int i = 1; i <= m; ++i) {
    		cin >> u >> v >> w >> c;
    		Add(u, v, w), Add(v, u, w);
    	}
    	dfs(1, -1, 0); //from node 1 find
    	mxd = 0;
    	t1 = mxu;
    	dfs(mxu, -1, 0);
    	t2 = mxu;
    	cout << mxd;
    }
    int main() {
    	solve();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    Computer

    求出所有节点离他最远的节点距离。

    #include 
    #include 
    #define rep(i, a, b) for(int i = a; i <= b; ++i)
    using namespace std;
    const int N = 1e4 + 10;
    int cnt, head[N];
    struct E {
        int to, nex, w;
    }e[N << 1];
    void Add(int u, int v, int w) { 
        e[++cnt].nex = head[u];
        e[cnt].to = v;
        e[cnt].w = w;  
        head[u] = cnt;
    }
    int n, mxd, mxu, t1, t2, dis[2][N];
    void dfs1(int u, int fa, int d) {
        if(d > mxd) {
            mxd = d, mxu = u;
        }
        for(int i = head[u]; i; i = e[i].nex) {
            int v = e[i].to;
            if(v == fa) continue;
            dfs1(v, u, d + e[i].w);
        }
    }
    void dfs2(int u, int fa, int d, int p) {
        dis[p][u] = d;
        for(int i = head[u]; i; i = e[i].nex) {
            int v = e[i].to;
            if(v == fa) continue;
            dfs2(v, u, d + e[i].w, p);
        }
    }
    int main() {
        while(cin >> n) {
            cnt = 0;
            rep(i, 0, n) head[i] = 0;
            rep(i, 0, n) dis[0][i] = dis[1][i] = 0;
            rep(i, 2, n) {
                int u, w;
                cin >> u >> w;
                Add(u, i, w), Add(i, u, w);
            }
            mxd = mxu = 0;
            dfs1(1, -1, 0);
            t1 = mxu;
            mxd = mxu = 0;
            dfs1(t1, -1, 0);
            t2 = mxu;
            dfs2(t1, -1, 0, 0);
            dfs2(t2, -1, 0, 1);
            rep(i, 1, n) cout << max(dis[0][i], dis[1][i]) << "\n";
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    F - Minimum Maximum Distance

    传送门
    相距更远的两个点, f f f值更大,求直径最远标记的两个点的中点距离就是答案。

    #include 
    #define int long long 
    #define pii pair<int, int>
    #define debug(a) cout << #a << "=" << a <<"\n";
    #define ios ios::sync_with_stdio(false), cin.tie(0);
    #define rep(i, a, b) for(int i = a;i <= b; ++i)
    #define multi int t;cin >> t;for(int i = 1;i <= t; ++i) solve()
    
    using namespace std; 
    const int N = 2e5 + 10;
    struct node {
    	int to, nex;
    }e[N << 1];
    int cnt, head[N];
    void Add(int u, int v) {
    	e[++cnt].nex = head[u];
    	e[cnt].to = v;
    	head[u] = cnt;
    }
    int n, m, a[N], f[N];
    map<int,int> mp;
    int mxd, mxu;
    
    void dfs(int u, int fa, int d) {
    	if(d > mxd && mp[u]) {
    		mxu = u;
    		mxd = d;
    	}
    	for(int i = head[u]; i; i = e[i].nex) {
    		int v = e[i].to;
    		if(v == fa) continue;
    		dfs(v, u, d + 1);
    	}
    }
    
    void solve() {
        cin >> n >> m;
        int x, st, u, v;
        mp.clear();
        mxd = cnt = 0;
        rep(i, 1, n) head[i] = 0;
        rep(i, 1, m) {
        	cin >> x, mp[x]++;
        	st = x; //start point
        }
        rep(i, 2, n) {
        	cin >> u >> v;
        	Add(u, v), Add(v, u);
        }
        if(m == 1) {
        	cout << "0\n";
        	return;
        }
        dfs(st, -1, 0);
        mxd = 0;
        dfs(mxu, -1, 0);
        cout << (mxd + 1) / 2 << '\n';
    }
    
    signed main() {
        ios;
        multi;
        return 0;
    }   
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
  • 相关阅读:
    net-java-php-python-教学资源管理系统hsg修改版计算机毕业设计程序
    快速构建高质量中文APP登录注册页面Figma源文件
    JVM:垃圾收集器与内存分配策略(2)
    线性表的应用 —— 双向链表 && 循环链表
    【数组】大数加法(正整数)
    20、Python实战项目:构建一个简单的Python应用
    CSP 2020 入门级第一轮1~17题解析
    shell: 遍历目录下的文件并查看
    fastjson(反序列化)漏洞复现
    【项目实践】Pyside6+Qtdesigner:登录窗体设计
  • 原文地址:https://blog.csdn.net/weixin_51552756/article/details/133827799