daimayuan(代码源oj)最长路径(树形dp,无向树换根dp)

题目传送门

daimayuan(代码源oj)最长路径(树形dp,无向树换根dp)_第1张图片

/*********************************************************************
    程序名:
    版权: Joecai
    作者: Joecai
    日期: 2022-04-14 19:16
    说明:
*********************************************************************/
#include 
using namespace std;
#define x first
#define y second
# define rep(i,be,en) for(int i=be;i<=en;i++)
# define pre(i,be,en) for(int i=be;i>=en;i--)
#define ll long long
#define endl "\n"
#define LOCAL
#define pb push_back
//#define int	long long
typedef pair<ll, ll> PII;
#define eb emplace_back
#define sp(i) setprecision(i)
const int N = 2e5 + 10, INF = 0x3f3f3f3f;


int n;
vector<int>g[N];
int  f[N][2][2];//以i为子树的最长路径和第二长路径 和他们的点
int v[N];//v[y] 记录了 y 号点的父亲 x 号点作为它的子树时从里面连上来的到 y 号点的最长路径


void dfs(int i, int fa)
{
	for (auto j : g[i])
	{
		if (j == fa) continue;
		dfs(j, i);
		if (f[j][0][0] + 1 > f[i][0][0])
		{
			f[i][1][0] = f[i][0][0], f[i][1][1] = f[i][0][1], f[i][0][0] = f[j][0][0] + 1, f[i][0][1] = j;
		} else if (f[j][0][0] + 1 > f[i][1][0])
		{
			f[i][1][1] = j, f[i][1][0] = f[j][0][0] + 1;
		}
	}
}



void dfs1(int i, int fa)
{
	for (auto j : g[i])
	{
		if (j == fa) continue;

		if (f[i][0][1] == j)
		{
			v[j] = 1 + max(f[i][1][0], v[i]);
		} else
		{
			v[j] = 1 + max(f[i][0][0], v[i]);
		}
		dfs1(j, i);
	}
}



void solve()
{
	cin >> n;
	for (int i = 1; i <= n - 1; i++)
	{
		int x, y;
		cin >> x >> y;
		g[x].push_back(y);
		g[y].push_back(x);
	}

	dfs(1, 0);

	dfs1(1, 0);
	for (int i = 1; i <= n; i++)
	{
		cout << f[i][1][0] + f[i][0][0] + v[i] - min({f[i][1][0], f[i][0][0], v[i]}) << endl;;
	}

}




signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	//#ifdef LOCAL
	//freopen("data.in.txt","r",stdin);
	//freopen("data.out.txt","w",stdout);
	//#endif
	int __ = 1;
	//cin>>__;
	while (__--)
	{
		solve();
	}
	return 0;
}


你可能感兴趣的:(动态规划,c++,算法)