您的位置:首页 > 其它

[hihocoder 1050]求树的最长链

2017-10-14 12:59 405 查看
题目链接:http://hihocoder.com/problemset/problem/1050

两种方法:

1. 两遍dfs,第一次随便找一个根,找到距离这个根最远的点,这个点必然是最长链的一端。第二次就用这个端点做一遍dfs,最远的点就是另一端。

#include<bits/stdc++.h>
using namespace std;

const int maxn=100005;
int d[maxn];
vector<int> G[maxn];

void dfs(int u,int fa,int now)
{
d[u]=now;
for (int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if (v!=fa) dfs(v,u,now+1);
}
}

int main()
{
int n;
scanf("%d",&n);
for (int i=0;i<n-1;i++)
{
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs(1,0,0);
int ma=0,maj=1;
for (int i=1;i<=n;i++)
{
if (d[i]>ma)
{
ma=d[i];
maj=i;
}
}
dfs(maj,0,0);
int ans=0;
for (int i=1;i<=n;i++) ans=max(ans,d[i]);
printf("%d",ans);
return 0;
}


2. 树形dp。记dp[i][0/1]表示以i为lca的最长链和次长链的长度,一遍dfs更新就好了。

#include<bits/stdc++.h>
using namespace std;

const int maxn=100005;
int dp[maxn][2];
vector<int> G[maxn];

void dfs(int u,int fa)
{
for (int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if (v!=fa) dfs(v,u);
}
if (G[u].size()<=2)
{
for (int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if (v!=fa) dp[u][0]=dp[v][0]+1;
}
}
else
{
for (int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if (v!=fa)
{
if (dp[v][0]+1>dp[u][0])
{
dp[u][1]=dp[u][0];
dp[u][0]=dp[v][0]+1;
}
else dp[u][1]=max(dp[v][0]+1,dp[u][1]);
}
}
}
}

int main()
{
int n;
scanf("%d",&n);
G[1].push_back(0);
for (int i=0;i<n-1;i++)
{
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs(1,0);
int ans=0;
for (int i=1;i<=n;i++) ans=max(ans,dp[i][0]+dp[i][1]);
printf("%d",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: