[樹的直徑] Codeforces 804D Round #411 (Div. 1) D. Expected diameter of a tree

來源:互聯網
上載者:User

這個只要知道兩個子樹連在一起的直徑端點必然是各自直徑的端點就好了
然後瞎枚舉一通
只要知道 ∑i∑jmin{sizei,sizej},∑isizei=n \sum_i\sum_j min\{size_i,size_j\} ,\sum_i size_i=n是 O(nn√) O(n\sqrt n)的就好了

#include<cstdio>#include<cstdlib>#include<algorithm>#include<vector>#include<map>#define pb push_backusing 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].vint 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(abcd(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;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.