【题目】
hdu6567
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=6567
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 336 Accepted Submission(s): 129
Problem Description
Avin has two trees which are not connected. He asks you to add an edge between them to make them connected while minimizing the function , where represents the number of edges of the path from to . He is happy with only the function value.
Input
The first line contains a number . In each of the following lines, there are two numbers and , meaning that there is an edge between and . The input is guaranteed to contain exactly two trees.
Output
Just print the minimum function value.
Sample Input
3 1 2
Sample Output
4
Source
2019CCPC-江西省赛(重现赛)- 感谢南昌大学
【题意】
给两个树,连一条边连接两颗树,问如何连接使得树上两两之间的距离和最小。
【思路】
刚开始想的是找两颗树的重心连接,一直wa就换成下面这个思路:设dp[u] 为从u节点出发到达u子树所有节点的距离和。
那么连接就是两颗树的最小u节点连接即可。
那么我们可以一次dfs预处理所有节点到达儿子、孙子节点的距离和。
然后通过换根dp就可以得到所有的dp[i]了。
连接ccurid1,curid2跑一遍dfs3计算总距离即可
【代码】
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
vector<int>G[N];
int n;
ll sz[N],dp[N],ty[N];
int curid1,curid2,curid;
void dfs1(int u,int fa)
{
sz[u]=1;
ty[u]=1;
for(int v:G[u])
{
if(v==fa) continue;
dfs1(v,u);
sz[u]+=sz[v];
dp[u]=dp[u]+dp[v]+sz[v];
}
}
ll ans;
void dfs2(int u,int fa)
{
if(dp[u]<ans){
ans=dp[u];
curid=u;
}
ans=min(ans,dp[u]);
for(int v:G[u])
{
if(v==fa) continue;
ll tmp=dp[u]-dp[v]-sz[v];
dp[v]+=tmp+sz[u]-sz[v];
sz[v]+=sz[u]-sz[v];
dfs2(v,u);
}
}
void dfs3(int u,int fa)
{
sz[u]=1;
for(int v:G[u])
{
if(v==fa) continue;
dfs3(v,u);
sz[u]+=sz[v];
ans+=sz[v]*(n-sz[v]);
}
}
int main()
{
cin>>n;
for(int i=1;i<=n-2;++i)
{
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
int ed;
dfs1(1,-1);
ans=0x3f3f3f3f3f3f3f3f;
curid=1;
dfs2(1,-1);//开始换根
curid1=curid;
for(int i=1;i<=n;++i) if(ty[i]==0){ed=i;break;}
dfs1(ed,-1);
ans=0x3f3f3f3f3f3f3f3f;
curid=ed;
dfs2(ed,-1);//开始换根
curid2=curid;
G[curid1].push_back(curid2);
ans=0;
memset(sz,0,sizeof(sz));
dfs3(curid1,-1);
printf("%lld\n",ans);
}