• P3232 [HNOI2013]游走


    吐槽

    傻了傻了,对着题解改了好长时间最后发现是自己忘了调用高斯消元了。。。

    思路

    期望题,分配编号,显然编号大的分给贡献次数小的,所以需要知道每个边被经过次数的期望
    然后边被经过的次数的期望就是连接的两个点到它的次数的期望求和,点走哪条边次数的期望相等(都是1/度数)
    然后就是求每个点的次数的期望,正推,高斯消元
    注意因为计算的是次数的期望,所以f1要加上1(开局经过一次)且所有的点都不能从fn转移来(因为到n就结束了,所以消元的时候也不用管fn

    代码

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #define int long long
    #define double long double
    using namespace std;
    const double eps=1e-9;
    int n,m,u[1010000],v[1010000],fir[1010],nxt[1010000],d[1010],cnt;
    double a[510][510],ans=0,Ex[1010000];
    struct Edge{
        int u,v;
    }E[1010000];
    void gauss(void){
        for(int i=1;i<n;i++){
            for(int j=i;j<n;j++){
                if(fabs(a[j][i])>eps){
                    for(int k=1;k<=n;k++)
                        swap(a[i][k],a[j][k]);
                    break;
                }
            }
            for(int j=1;j<n;j++){
                if(j==i)
                    continue;
                double rate=a[j][i]/a[i][i];
                for(int k=i;k<=n;k++)
                    a[j][k]=a[j][k]-rate*a[i][k];
            }
        }
        for(int i=1;i<n;i++)
            a[i][n]=a[i][n]/a[i][i];
        return;
    }
    void addedge(int ui,int vi){
        ++cnt;
        u[cnt]=ui;
        v[cnt]=vi;
        d[ui]++;
        nxt[cnt]=fir[ui];
        fir[ui]=cnt;
    }
    void build(void){
        // a[n][n]=1;
        a[1][n]=1;
        for(int i=1;i<n;i++){
            a[i][i]+=1;
            // a[i][n+1]+=1;
            for(int j=fir[i];j;j=nxt[j]){
                if(v[j]!=n)
                a[i][v[j]]-=1.0/d[v[j]];
            }
        }
    }
    signed main(){
        scanf("%lld %lld",&n,&m);
        for(int i=1;i<=m;i++){
            int a,b;
            scanf("%lld %lld",&a,&b);
            addedge(a,b);
            addedge(b,a);
            E[i].u=a;
            E[i].v=b;
        }
        build();
        gauss();
        for(int i=1;i<=m;i++){
            Ex[i]+=a[E[i].u][n]/d[E[i].u];
            Ex[i]+=a[E[i].v][n]/d[E[i].v];
        }
        sort(Ex+1,Ex+m+1);
        for(int i=1,j=m;i<=m;i++,j--)
            ans=ans+j*Ex[i]*1.0;
        printf("%.3Lf
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    Windows Service 2016 DatacenterStandEmbedded激活方法
    批处理文件设置IP以及DNS
    C#类的一些基础知识(静态方法可以不用实例化调用)
    Dynamics Crm Plugin插件注册的问题及解决方案(持续更新。。。。。。)
    【转载】C# get 与set的一些说明
    C#补位函数PadLeft和PadRight
    Kubernetes集群调度之Scheduler
    Kubernetes集群控制之ControllerManager
    Kubernetes集群大脑之apiserver
    Kubernetes集群存储之etcd
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10534611.html
Copyright © 2020-2023  润新知