• 【Codeforces 1086B】Minimum Diameter Tree


    【链接】 我是链接,点我呀:)
    【题意】

    题意

    【题解】

    统计叶子节点个数m 把每条和叶子节点相邻的边权设置成s/cnt就可以了 这样答案就是2*s/m(直径最后肯定是从一个叶子节点开始,到另外一个叶子节点结束)

    证明:
    设dis(i,j)表示节点i和节点j之间的权值和
    设a[1],a[2]..a[m]是m个叶子节点

    (max(dis(a[i],a[j])) >= ∑frac{dis(a[i],a[j]) }{ frac{m*(m-1)}{2|} })
    (frac{m*(m-1)}{2}*max(dis(a[i],a[j]))>=∑dis(a[i],a[j]))
    而会发现每一条边对不等式右边的贡献至少是为(1*(m-1))的也就是m-1
    最坏的情况就是,每条边左边只有一个叶子节点,然后右边有m-1个叶子节点。贡献就是最小的m-1
    所以(frac{m*(m-1)}{2}*max(dis(a[i],a[j]))>=∑dis(a[i],a[j])>=(m-1)*∑e[i]=(m-1)*s)
    然后就能得到max(dis(a[i],a[j]))>=2*s/m

    【代码】

    #include <bits/stdc++.h>
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i>= b;i--)
    #define ll long long
    using namespace std;
    
    const int N = 1e5;
    
    int n,s;
    int du[N+10];
    
    int main(){
        ios::sync_with_stdio(0),cin.tie(0);
        cin >> n >> s;
        rep1(i,1,n-1){
            int x,y;
            cin >> x >> y;
            du[x]++;du[y]++;
        }
        int m = 0;
        double ans = 2*s;
        rep1(i,1,n){
            if (du[i]==1){
                m++;
            }
        }
        ans = ans/m;
        cout<<fixed<<setprecision(15)<<ans<<endl;
        return 0;
    }
    
    
  • 相关阅读:
    Session攻击(会话劫持+固定)与防御
    console调试命令
    javascript获取当前url
    搞不清FastCgi与PHP-fpm之间是个什么样的关系
    MySQL基本语句优化10个原则
    PHP获取类名及所有函数名
    js闭包
    字段、方法、属性
    python面向对象之类成员修饰符
    实现Python代码发送邮件
  • 原文地址:https://www.cnblogs.com/AWCXV/p/10679237.html
Copyright © 2020-2023  润新知