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;
}

 

posted @ 2020-01-24 01:02  无名菜鸟1  阅读(333)  评论(0编辑  收藏  举报