• [BZOJ 3143][Hnoi2013]游走(高斯消元+期望)


    Description

    一个无向连通图,顶点从1编号到N,边从1编号到M。
    小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编号的分数。当小Z 到达N号顶点时游走结束,总分为所有获得的分数之和。
    现在,请你对这M条边进行编号,使得小Z获得的总分的期望值最小。

    Solution

    对于点u(u≠1):到达u的概率 f[u]=∑f[v]/d[v] (Edges(u,v))

    而f[1]=∑f[v]/d[v]+1 (Edges(1,v))

    高斯消元可以求出所有点的概率

    对于每条边 到达边i的概率 p[i]=f[u]/d[u]+f[v]/d[v]

    贪心的编号然后求出期望就好了

    好像BZOJ上的数据会比较水,洛谷数据…卡精度

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define eps 1e-7
    using namespace std;
    int n,m,head[505],cnt=0,d[505];
    double a[505][505],f[505],p[250005];
    struct Node
    {
        int next,from,to;
    }Edges[500005];
    void addedge(int u,int v)
    {
        Edges[++cnt].next=head[u];
        head[u]=cnt;
        Edges[cnt].from=u;
        Edges[cnt].to=v;
    }
    void Gauss()
    {
        for(int i=1;i<=n;i++)
        {
            int maxline=i;
            for(int j=i+1;j<=n;j++)
            if(a[j][i]>a[maxline][i])maxline=j;
            if(maxline!=i)
            for(int j=i;j<=n+1;j++)
            swap(a[maxline][j],a[i][j]);
            for(int j=i+1;j<=n;j++)
            {
                if(fabs(a[j][i])<eps)continue;
                double t=a[j][i]/a[i][i];
                for(int k=i;k<=n+1;k++)
                a[j][k]-=t*a[i][k];
            }
        }
        for(int i=n;i>0;i--)
        {
            for(int j=n;j>i;j--)
            a[i][n+1]-=f[j]*a[i][j];
            f[i]=a[i][n+1]/a[i][i];
        }
    }
    int main()
    {
        memset(head,-1,sizeof(head));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            addedge(u,v);
            addedge(v,u);
            d[u]++,d[v]++;
        }
        for(int i=1;i<n;i++)
        {
            a[i][i]=1;
            for(int j=head[i];~j;j=Edges[j].next)
            a[i][Edges[j].to]=-1.0/d[Edges[j].to];
        }
        a[1][n+1]=1,a[n][n]=1;
        Gauss();
        for(int i=1;i<=cnt;i+=2)
        {
            int u=Edges[i].from,v=Edges[i].to;
            p[(i+1)>>1]+=(double)f[u]/d[u];
            p[(i+1)>>1]+=(double)f[v]/d[v];
        }
        sort(p+1,p+1+m);
        double ans=0;
        for(int i=1;i<=m;i++)
        ans+=p[i]*(m-i+1);
        printf("%.3lf
    ",ans);
        return 0;
    } 

    被卡精度)

  • 相关阅读:
    对比.NET PetShop和Duwamish来探讨Ado.NET的数据库编程模式
    找到了一个动态加载web用户自定义控件的问题,不知道算不算是微软的bug
    今天碰到了一个取 REMOTE_USER 的问题
    解决震荡波补丁引起的oracle不能启动
    有几个gmail的邀请,需要的留个言吧。
    一种插入记录的方式,撇开效率,看看对不对
    Regex 类介绍
    Page执行周期
    一段xml deserialize解释
    突然产生的一个想法,写一个基类,用来完成对LoadControl后续操作进行管理
  • 原文地址:https://www.cnblogs.com/Zars19/p/6819037.html
Copyright © 2020-2023  润新知