Description
Input
Output
Sample Input
4 4
1 3
2 1
4 3
4 3
4 1
1 2
Sample Output
68
Data Constraint
算法讨论
问题的关键是如何求出两棵树的重心,那就是f[i],即所有点到点i的距离,首先dfs一次求出f[1]和z[i](i的子树的大小),那么就可以进行树形dp,父亲节点为i,儿子节点为j,f[j]:=f[i]+n-2*f[j],找出左右两棵树最小的f[i],相连即可。
type node=^link;
link=record
g:longint;
next:node;
end;
var
nd:array[1..2,1..300000]of node;
n,m,l:longint;
f,z:array[1..2,0..300000] of int64;
t:array[0..300000] of boolean;
procedure dfs(wei,e:longint);
var
p:node;
begin
f[l,1]:=f[l,1]+e;
t[wei]:=false;
p:=nd[l,wei];
while p<>nil do
begin
if t[p^.g] then
begin
dfs(p^.g,e+1);
z[l,wei]:=z[l,wei]+z[l,p^.g]+1;
end;
p:=p^.next;
end;
end;
procedure df(wei:longint);
var
p:node;
begin
t[wei]:=false;
p:=nd[l,wei];
while p<>nil do
begin
if t[p^.g] then
begin
f[l,p^.g]:=f[l,wei]-2*(z[l,p^.g]+1);
if l=1 then inc(f[l,p^.g],n)
else inc(f[l,p^.g],m);
df(p^.g);
end;
p:=p^.next;
end;
end;
procedure ad(u,v,w:longint);
var
p:node;
begin
new(p);
p^.g:=v;
p^.next:=nd[w,u];
nd[w,u]:=p;
end;
var
u,v,i:longint;
sum,xx,yy:int64;
begin
assign(input,'a.in');reset(input);
readln(n,m);
for i:=1 to n-1 do
begin
readln(u,v);
ad(u,v,1);
ad(v,u,1);
end;
for i:=1 to m-1 do
begin
readln(u,v);
ad(u,v,2);
ad(v,u,2);
end;
fillchar(t,sizeof(t),true);
l:=1;
dfs(1,0);
fillchar(t,sizeof(t),true);
df(1);
fillchar(t,sizeof(t),true);
l:=2;
dfs(1,0);
fillchar(t,sizeof(t),true);
df(1);
xx:=9223372036854775807;
yy:=xx;
for i:=1 to n do
begin
if f[1,i]<xx then xx:=f[1,i];
sum:=sum+f[1,i];
end;
for i:=1 to m do
begin
if f[2,i]<yy then yy:=f[2,i];
sum:=sum+f[2,i];
end;
writeln(sum div 2+xx*m+yy*n+n*m);
end.