• 数学(概率):HNOI2013 游走


    【题目描述】

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

    【输入格式】

    第一行是正整数N和M,分别表示该图的顶点数 和边数,接下来M行每行是整数u,v(1≤u,v≤N),表示顶点u与顶点v之间存在一条边。 输入保证30%的数据满足N≤10,100%的数据满足2≤N≤500且是一个无向简单连通图。

    【输出格式】

    仅包含一个实数,表示最小的期望值,保留3位小数。

    【样例输入】

      3  3                
      2  3
      1  2
      1  3
      

    【样例输出】

    3.333

    【提示】

    (1,2)编号为1,边(1,3)编号2,边(2,3)编号为3

    这道题目,先求每个点经过的期望次数,我觉得一般是用正推的,然后贪心。

     

     

     

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <cstdio>
     5 #include <cmath>
     6 using namespace std;
     7 const int N=510,M=N*N;
     8 int n,m,e[M][2],d[N];
     9 long double A[N][N];
    10 double ans,w[M],x[N];
    11 void Guass_Elimination(){
    12     for(int i=1;i<n;i++){
    13         int p=i;
    14         for(int j=i+1;j<n;j++)
    15             if(fabs(A[p][i])<fabs(A[j][i]))
    16                 p=j;
    17         if(p!=i)
    18             for(int j=1;j<=n;j++)
    19                 swap(A[i][j],A[p][j]);
    20         long double tmp=A[i][i];
    21         for(int j=1;j<=n;j++)
    22             A[i][j]/=tmp;
    23         for(int j=1;j<n;j++)
    24             if(i!=j){
    25                 tmp=A[j][i];
    26                 for(int k=1;k<=n;k++)
    27                     A[j][k]-=tmp*A[i][k];
    28             }
    29     }
    30     for(int i=1;i<n;i++)
    31         x[i]=A[i][n];
    32 }
    33 int main(){
    34     freopen("walk.in","r",stdin);
    35     freopen("walk.out","w",stdout);
    36     scanf("%d%d",&n,&m);
    37     for(int i=1;i<=m;i++){
    38         scanf("%d%d",&e[i][0],&e[i][1]);
    39         d[e[i][0]]+=1;d[e[i][1]]+=1;
    40     }A[1][n]=1;
    41     for(int i=1;i<n;i++)A[i][i]=1;
    42     for(int i=1;i<=m;i++){
    43         if(e[i][0]==n||e[i][1]==n)continue;
    44         A[e[i][0]][e[i][1]]+=-1.0/d[e[i][1]];
    45         A[e[i][1]][e[i][0]]+=-1.0/d[e[i][0]];
    46     }
    47     Guass_Elimination();
    48     for(int i=1;i<=m;i++){
    49         w[i]+=x[e[i][0]]/d[e[i][0]];
    50         w[i]+=x[e[i][1]]/d[e[i][1]];
    51     }
    52     sort(w+1,w+m+1);
    53     for(int i=1;i<=m;i++)
    54         ans+=w[i]*(m-i+1);
    55     printf("%.3lf
    ",ans);    
    56     return 0;
    57 }

     

     

  • 相关阅读:
    训练yolov5识别木块的模型
    八叉树分割点云并优化网格实验记录
    八叉树分割点云实验记录
    给pcd添加头
    C++绘制点云 日志记录
    点云最小包围盒
    java list洗牌
    训练yolov5识别小黄球模型
    八叉树分割点云实验记录2
    pcd中 毫米转为米
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5922951.html
Copyright © 2020-2023  润新知