zoukankan      html  css  js  c++  java
  • 算法训练Maze

    #include<bits/stdc++.h>
    using namespace std;
    //见https://blog.csdn.net/sky980114/article/details/69038382
    //观察发现从某一个节点到达另一个节点的路径期望值等于路径中所有可能被遍历的边数之和,因为深搜的特点导致了遍历完一整棵树才能走
    // 准则2可以转化成准则1,因为准则2终点固定
    int n,x[100001],y[100001],son[100001]={0};
    long long sum=0,sumx=0,sumy=0,lf[100001];//最后再除,因为精度太高了
    vector<int> g[100001];//不用存权重,方便
    void dfs1(int k,int f){
        //用于求子节点数
        for(int i=0;i<g[k].size();i++){
            //遍历vector
            if(g[k][i]!=f){
                dfs1(g[k][i],k);
                son[k]+=son[g[k][i]];
                son[k]++;//如果没有这个那么都是0,求的是 子节点 数,因为是子节点数少了一个所以+1
                //因为只有非叶子才能++,导致最下面的分叉是叶子节点 son=0 在++
                lf[k]+=lf[g[k][i]];//这是包括当前点和子节点的x和,因为初始化了
            }
        }
    }
    //不用for用dfs因为需要子树关系,lf
    void dfs2(int k,int f){
        //具体求值
        //预处理,全部安照方式2,求所有不是k的点到k的和,因为按照方式2需要确定终点,所以。。
        sum+=(n-1-son[k])*(sumx-x[k])*y[k];
        for(int i=0;i<g[k].size();i++){
            if(g[k][i]!=f){
                dfs2(g[k][i],k);//对子节点求完
                //修改,对方式1的进行修正,利用lf
                sum-=(n-1-son[k])*lf[g[k][i]]*y[k];
                sum+=(son[g[k][i]]+1)*lf[g[k][i]]*y[k];
            }
        }
    }
    int main() {
        cin>>n;
        for(int i=0;i<n-1;i++){
            int x,y;
            cin>>x>>y;
            g[x].push_back(y);
            g[y].push_back(x);
        }
        for(int i=1;i<=n;i++){
            cin>>x[i]>>y[i];
            sumx+=x[i];
            sumy+=y[i];
            lf[i]=x[i];//lf用于优化,因为发现 开始:某个点 结束:他的父节点,对于这个点的子节点,期望和这个点到父节点相同,这样可以优化
        }
        dfs1(1,-1);
        dfs2(1,-1);
        printf("%.11f
    ",1.0*sum/sumx/sumy);
        return 0;
    }
  • 相关阅读:
    react阻止默认事件
    react组件直接在document上添加事件
    react组件更新swiper
    react组件里阻事件冒泡
    react生命周期获取异步数据
    加油
    redis教程
    redis哨兵机制
    redis复制
    致自己
  • 原文地址:https://www.cnblogs.com/MorrowWind/p/12416345.html
Copyright © 2011-2022 走看看