This is as long as you know that the two sub-trees are connected to each other at the end of their respective diameters.
And then blindly enumerate a pass
Just know ∑i∑jmin{sizei,sizej},∑isizei=n \sum_i\sum_j min\{size_i,size_j\}, \sum_i size_i=n is O (nn√) O (n\sqrt N) just fine.
#include <cstdio> #include <cstdlib> #include <algorithm> #include <vector> #include <map
> #define PB push_back using namespace std;
typedef pair<int,int> ABCD;
typedef long Long LL;
Inline char NC () {static Char buf[100000],*p1=buf,*p2=buf; Return p1==p2&& (p2= (p1=buf) +fread (Buf,1,100000,stdin), P1==P2)?
eof:*p1++;
} inline void read (int &x) {char c=nc (), b=1; for (;!
(c>= ' 0 ' && c<= ' 9 '); C=nc ()) if (c== '-') b=-1; for (x=0;c>= ' 0 ' && c<= ' 9 '; x=x*10+c-' 0 ', C=NC ());
X*=b;
} const int n=100005; struct edge{int u,v,next;}
g[n<<1];
int head[n],inum; inline void Add (int u,int v,int p) {g[p].u=u; G[p].v=v; G[p].next=head[u];
Head[u]=p;
} #define V g[p].v int depth[n],d[n];
int maxd,pos;
int rt[n],dm[n];
inline void dfs (int u,int fa,int z) {depth[u]=depth[fa]+1; rt[u]=z;
if (Depth[u]>maxd) maxd=depth[pos=u];
D[u]=max (d[u],depth[u]-1); for (int p=head[u];p; p=g[p].next) if (V!=FA) DFS (v,u,z);
} vector<ll> Cnt[n],sum[n];
inline ll Cnt (int x,int y) {if (Y>=cnt[x].size ()) return 0;
return cnt[x][y];
} inline ll Sum (int x,int y) {if (Y>=sum[x].size ()) return 0;
return sum[x][y];
} vector<int> Ab[n];
inline void count (int u,int fa,int z) {cnt[z][d[u]]++; sum[z][d[u]]+=d[u]; AB[Z].PB (U);
for (int p=head[u];p; p=g[p].next) if (V!=FA) count (v,u,z);
} int n,m,q;
Vector<abcd> que;
Double Ans[n];
Map<abcd,double> Map;
int main () {int x, y;
Freopen ("T.in", "R", stdin);
Freopen ("T.out", "w", stdout); Read (n); Read (m);
Read (Q);
for (int i=1;i<=m;i++) read (x), read (y), add (X,y,++inum), add (Y,x,++inum);
for (int i=1;i<=n;i++) if (!depth[i]) {maxd=0,pos=0;
DFS (i,0,i); int t=pos;
maxd=0,pos=0;
DFS (t,0,i);
Dm[i]=maxd-1; T=pos;
maxd=0,pos=0;
DFS (t,0,i);
Cnt[i].resize (Maxd), sum[i].resize (Maxd);
Count (I,0,i); for (int j=maxd-2;j>=0;j--) cnt[i][j]+=cnt[i][J+1],SUM[I][J]+=SUM[I][J+1];
} for (int i=1;i<=q;i++) {read (x); Read (y); x=rt[x]; Y=rt[y];
if (x==y) {printf (" -1\n"); continue;} if (Ab[x].size () >ab[y].size () | | (Ab[x].size () ==ab[y].size () && x>y))
Swap (x, y);
if (Map.count (x, y)) {printf ("%.10lf\n", MAP[ABCD (x, y)]); continue;}
ll Ans=0,dd=max (Dm[x],dm[y]);
for (int u:ab[x]) ans+=cnt (Y,dd-d[u]) * (1+d[u]) +sum (Y,dd-d[u]) + (Ab[y].size ()-cnt (Y,dd-d[u])) *dd;
printf ("%.10lf\n", MAP[ABCD (x, y)]= (double) ans/ab[x].size ()/ab[y].size ());
} return 0;
}