• randomwalking(10.2hu测)


    这里写图片描述

    这里写图片描述

    这里写图片描述

    分析:
    当时看到概率期望,光速弃疗
    写了一个n^2暴力,30分稳

    那我们就来看看正解:
    son记录和该节点直接相连的结点个数
    两遍dfs
    第一遍从叶子向根转移
    这里写图片描述

    第二遍dfs稍微有点难理解
    第二遍dfs处理以每个点为起点的概率(就是答案啦)
    从根向叶子转移
    f[1][0]=f[1][1]
    这里写图片描述
    这里写图片描述

    //这里写代码片
    #include<cstring>
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #define ll long long
    
    using namespace std;
    
    const int N=1000010;
    const double INF=1e17;
    const double eps=1e-8;
    int n;
    int a[N];
    struct node{
        int x,y,nxt;
    };
    node way[N<<1];
    int st[N],tot=0,ans,son[N];
    double ansx,f[N][2];
    
    int dcmp(double x)
    {
        if (fabs(x)<eps) return 0;
        else if (x>0) return 1;
        else return -1;
    }
    
    void add(int u,int w)
    {
        tot++;
        way[tot].x=u;way[tot].y=w;way[tot].nxt=st[u];st[u]=tot;
        tot++;
        way[tot].x=w;way[tot].y=u;way[tot].nxt=st[w];st[w]=tot;
    }
    
    void dfs_1(int now,int fa)
    {
        for (int i=st[now];i;i=way[i].nxt)
            if (way[i].y!=fa)
                son[now]++;
        if (fa!=0) son[now]++;
        for (int i=st[now];i;i=way[i].nxt)
            if (way[i].y!=fa)
            {
                dfs_1(way[i].y,now);
                if (fa!=0)
                   f[now][0]+=f[way[i].y][0]/(double)(son[now]-1);
                else f[now][0]+=f[way[i].y][0]/(double)son[now];
            }
        f[now][0]+=a[now];
    }
    
    void dfs_2(int now,int fa)
    {
        if (now==1) f[now][1]=f[now][0];
        else
        {
            double temp1=(f[fa][1]-a[fa])*son[fa];
            double temp2=temp1-f[now][0];
            double temp3=(f[now][0]-a[now])*(son[now]-1);
            if (son[fa]>1)
                f[now][1]=(temp2/(double)(son[fa]-1)+a[fa])/(double)son[now]+temp3/(double)son[now];
            else 
                f[now][1]=a[fa]/(double)son[now]+temp3/(double)son[now];
            f[now][1]+=a[now];
        }
        for (int i=st[now];i;i=way[i].nxt)
            if (way[i].y!=fa)
                dfs_2(way[i].y,now);
    }
    
    int main()
    {
        freopen("walking.in","r",stdin);  
        freopen("walking.out","w",stdout);
        scanf("%d",&n);
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);
        for (int i=1;i<n;i++)
        {
            int u,w;
            scanf("%d%d",&u,&w);
            add(u,w);
        }
        if (n==1) {
            printf("1
    ");
            return 0;
        }
        ansx=INF;
        dfs_1(1,0);
        dfs_2(1,0);
        for (int i=1;i<=n;i++)
            if (f[i][1]<ansx)
               ansx=f[i][1],ans=i;
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    心跳机制
    C++虚继承和虚基类
    STL,ATL与WTL
    C# Task的暂停与终止
    C#继承
    C#线程同步问题
    CourtAi发布配置文件修改说明
    阿里云虚拟主机https化步骤第一篇,申请证书(笔记)
    linux 服务器重启指令
    .net core 发布到iis问题 HTTP Error 500.30
  • 原文地址:https://www.cnblogs.com/wutongtong3117/p/7673101.html
Copyright © 2020-2023  润新知