codeforces805F Expected diameter of a tree

题目大意:

给定一个森林,有若干个询问,每次询问在第i棵树中随机选一个点,在第j棵树中随机选一个点并将它们相连后树的直径的期望值。

对每棵树求出它的直径d,对每个点求出它到树上最远点的距离f,那么选择x、y点时树的直径就是:

max(d[i],d[j],f[x]+f[y]+1)

对每棵树中点的f排序。

枚举一棵树中每个点,再二分另一棵树的f就能统计答案了。

具体看代码。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
using namespace std;
#define ll long long
#define N 100010
vector<int>g[N],e[N];
vector<ll>Sum[N];
map<int,double>M[N];
int f[N],i,j,n,m,x,y,Q,s[N],d[N],a[N],Ma,Y;
bool Flag;
double Ans,k;
inline int Max(int x,int y){return x<y?y:x;}
inline int Find(int x){return f[x]==x?x:f[x]=Find(f[x]);}
inline void Dfs1(int x,int p,int s){
    if(Flag)return;
    if(d[x]){Flag=1;return;}
    if(s>Ma)Ma=s,y=x;
    d[x]=Max(d[x],s);
    for(int i=0;i<e[x].size();i++)
    if(e[x][i]!=p)Dfs1(e[x][i],x,s+1);
}
inline void Dfs2(int x,int p,int s){
    if(s>Ma)Ma=s,y=x;
    d[x]=Max(d[x],s);
    for(int i=0;i<e[x].size();i++)
    if(e[x][i]!=p)Dfs2(e[x][i],x,s+1);
}
inline bool Calc(int x){
    Flag=0;Ma=-1;
    Dfs1(x,0,0);
    if(Flag)return 1;
    Ma=-1;
    Dfs2(y,0,0);
    Dfs2(y,0,0);
    return 0;
}
inline int Binary(int x,int y){
    if(g[x][0]>=y)return -1;
    if(g[x][g[x].size()-1]<=y)return g[x].size()-1;
    int l=0,r=g[x].size()-2,Mid;
    while(l<=r){
        Mid=l+r>>1;
        if(g[x][Mid]<=y&&g[x][Mid+1]>=y)return Mid;
        if(g[x][Mid]>y)r=Mid-1;else l=Mid+1;
    }
    return l;
}
int main(){
    scanf("%d%d%d",&n,&m,&Q);
    for(i=1;i<=n;i++)f[i]=i;
    for(i=1;i<=m;i++)scanf("%d%d",&x,&y),f[Find(x)]=Find(y),e[x].push_back(y),e[y].push_back(x);
    for(i=1;i<=n;i++){
        if(Find(i)==i&&Calc(i))a[i]=-1;
        s[f[i]]++;
    }
    for(i=1;i<=n;i++)
    if(a[f[i]]!=-1)a[f[i]]=Max(a[f[i]],d[i]),g[f[i]].push_back(d[i]);
    for(i=1;i<=n;i++)
    if(s[i]&&a[i]!=-1){
        sort(g[i].begin(),g[i].end());
        Sum[i].push_back(g[i][0]);
        for(j=1;j<g[i].size();j++)Sum[i].push_back(Sum[i][j-1]+g[i][j]);
    }
    while(Q--){
        scanf("%d%d",&x,&y);
        x=Find(x);y=Find(y);
        if(x==y||a[x]==-1||a[y]==-1){puts("-1");continue;}
        if(s[x]>s[y]||(s[x]==s[y]&&x>y))swap(x,y);
        k=M[x][y];
        if(k){printf("%.9lf\n",k);continue;}
        Ma=Max(a[x],a[y]);Y=g[y].size();
        for(i=Ans=0;i<g[x].size();i++){
            j=Binary(y,Ma-g[x][i]-1);
            if(j>-1)Ans+=1ll*Ma*(j+1);
            if(j<Y-1)Ans+=Sum[y][Y-1]-(j>-1?Sum[y][j]:0)+1ll*(Y-j-1)*(g[x][i]+1);
        }
        Ans/=1ll*s[x]*s[y];
        M[x][y]=Ans;
        printf("%.9lf\n",Ans);
    }
    return 0;
}

codeforces805F

时间: 2024-08-05 17:46:28

codeforces805F Expected diameter of a tree的相关文章

543. Diameter of Binary Tree

题目: Given a binary tree, you need to compute the length of the diameter of the tree. The diameter of a binary tree is the length of the longest path between any two nodes in a tree. This path may or may not pass through the root. Example:Given a bina

LeetCode 543. Diameter of Binary Tree (二叉树的直径)

Given a binary tree, you need to compute the length of the diameter of the tree. The diameter of a binary tree is the length of the longestpath between any two nodes in a tree. This path may or may not pass through the root. Example:Given a binary tr

[LeetCode] Diameter of Binary Tree 二叉树的直径

Given a binary tree, you need to compute the length of the diameter of the tree. The diameter of a binary tree is the length of the longestpath between any two nodes in a tree. This path may or may not pass through the root. Example:Given a binary tr

leetcode543 - Diameter of Binary Tree - easy

Given a binary tree, you need to compute the length of the diameter of the tree. The diameter of a binary tree is the length of the longest path between any two nodes in a tree. This path may or may not pass through the root. Example: Given a binary

543. Diameter of Binary Tree(两节点的最长路径)

Given a binary tree, you need to compute the length of the diameter of the tree. The diameter of a binary tree is the length of the longest path between any two nodes in a tree. This path may or may not pass through the root. Example:Given a binary t

14.Diameter of Binary Tree(二叉树的直径)

Level: ??Easy 题目描述: Given a binary tree, you need to compute the length of the diameter of the tree. The diameter of a binary tree is the length of the longest path between any two nodes in a tree. This path may or may not pass through the root. Exam

【leetcode_easy】543. Diameter of Binary Tree

problem 543. Diameter of Binary Tree 参考 1. Leetcode_easy_543. Diameter of Binary Tree; 完 原文地址:https://www.cnblogs.com/happyamyhope/p/10943221.html

[LC] 543. Diameter of Binary Tree

Given a binary tree, you need to compute the length of the diameter of the tree. The diameter of a binary tree is the length of the longestpath between any two nodes in a tree. This path may or may not pass through the root. Example:Given a binary tr

543. 二叉树的直径 Diameter of Binary Tree

/** * Definition for a binary tree node. * public class TreeNode { * public int val; * public TreeNode left; * public TreeNode right; * public TreeNode(int x) { val = x; } * } */ public class Solution { public int DiameterOfBinaryTree(TreeNode root)