• Three Paths on a Tree


    题意:在一棵树上找三个不同点,使的三点之间的路径通过最多的不同边。

    解法:将树看一条长链像有机化学里的结构式,可以肯定长链的两端点(两次dfs找出最长链)是答案中的两点,第三个点有两种情况:

    1、没有支链即只有一条长链第三点即为不同于端点的任意一点。

    2、有支链,找一条最长的支链的端点(bfs找最长支链)即可。

    //#include <bits/stdc++.h>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <stdio.h>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <string.h>
    #include <vector>
    #define ME(x , y) memset(x , y , sizeof(x))
    #define SF(n) scanf("%d" , &n)
    #define rep(i , n) for(int i = 0 ; i < n ; i ++)
    #define INF  0x3f3f3f3f
    #define mod 20191117
    #define PI acos(-1)
    #define x first
    #define y second
    using namespace std;
    typedef long long ll ;
    
    vector<int>p;
    vector<vector<int>>g;
    
    pair<int , int> dfs(int u , int pre = -1 , int dis = 0)
    {
        p[u] = pre;
        pair<int , int> res = make_pair(dis  , u);
        for(auto to : g[u])
        {
            if(pre == to) continue ;
            res = max(res , dfs(to , u , dis+1));
        }
        return res ;
    }
    
    int main()
    {
        int n ;
        scanf("%d" , &n);
        p = vector<int>(n);
        g = vector<vector<int>>(n);
        for(int i = 0 ; i < n-1 ; i++)
        {
            int u , v ;
            scanf("%d%d" , &u , &v);
            u-- , v-- ;
            g[u].push_back(v);
            g[v].push_back(u);
        }
        vector<int>diam;
        pair<int , int>db , sb;
    
        db = dfs(0);
        sb = dfs(db.y);
        int v = sb.y ;
        while(v != db.y)
        {
            diam.push_back(v);
            v = p[v];
        }
        diam.push_back(v);
        if(diam.size() == n)
        {
            cout << n - 1 << " " << endl << diam[0] + 1 << " " << diam[1]+1 << " " << diam.back() + 1 << endl;
        }
        else{
            vector<int>d(n , -1);
            queue<int>q;
            for(auto &i : diam)
            {
                q.push(i);
                d[i] = 0;
            }
            while(!q.empty())
            {
                int v = q.front();
                q.pop();
                for(auto to : g[v])
                {
                    if(d[to] == -1)
                    {
                        d[to] = d[v] + 1;
                        q.push(to);
                    }
                }
            }
            pair<int , int> mx = make_pair(d[0] , 0);
            for(int v = 1 ; v < n ; v++)
            {
                mx = max(mx , make_pair(d[v] , v));
            }
            cout << diam.size() - 1 + mx.x << endl << diam[0]+1 << " " << mx.y + 1 << " " << diam.back() + 1 << endl;
        }
    
    
    
        return 0;
    }
    
  • 相关阅读:
    ESP8266 STA TCP 客户端配置并连接通信
    Modbus CRC16 校验计算函数
    自写简易版从机Modbus
    STM32CubeIDE查看内存使用情况
    WPF 样式Style
    WPF选项卡页面分离之Page调用Window类
    WPF 多个选项卡TabControl 页面分离
    STM32Cube IDE 汉字字体变小解决办法
    浮点数double相等性比较
    Ling应用
  • 原文地址:https://www.cnblogs.com/nonames/p/12231769.html
Copyright © 2020-2023  润新知