zoukankan      html  css  js  c++  java
  • 洛谷P3232 [HNOI2013]游走(高斯消元+期望)

    传送门

    所以说我讨厌数学……期望不会高斯消元也不会……好不容易抄好了高斯消元板子被精度卡成琪露诺了……

    首先,我们先算出走每一条边的期望次数,那么为了最小化期望,就让大的期望次数乘上小编号

    边的期望次数是多少呢?可以先算出点的概率

    $p(u,v)=frac{p[u]}{d[u]}+frac{p[v]}{d[v]}$

    $p[u]$表示经过这个点的期望次数,$d[u]$表示这个点的度数

    那么点的期望次数怎么求?

    $p[u]=sum_{(u,v)in E}frac{p[v]}{d[v]}$

    然后发现这玩意儿会产生环,因为一个点的期望次数需要由它周围的点推出,他周围的点又需要它推出

    那么我们考虑列方程,用高斯消元求解

    代码如下

    for(int i=1;i<n;++i){
        f[i][i]=1.0;
        for(int j=head[i];j;j=Next[j])
        if(ver[j]!=n)
        f[i][ver[j]]=-1/d[ver[j]];
    }
    f[1][n]=1;

    其中$f[i][j]$表示从$j$转移到$i$的期望次数

    这个方程实际上是$这个点的期望次数*1-所有相邻的点转移过来的期望次数=0$

    然后因为一开始在第一个点,所以第一个点必定到,设为$f[1][n]=1$

     1 //minamoto
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
     8 char buf[1<<21],*p1=buf,*p2=buf;
     9 inline int read(){
    10     #define num ch-'0'
    11     char ch;bool flag=0;int res;
    12     while((ch=getc())>'9'||ch<'0')
    13     (ch=='-')&&(flag=true);
    14     for(res=num;(ch=getc())<='9'&&ch>='0';res=res*10+num);
    15     (flag)&&(res=-res);
    16     #undef num
    17     return res;
    18 }
    19 const int N=605;const double eps=1e-7;
    20 int ver[N*N*2],Next[N*N*2],from[N*N*2],to[N*N*2],head[N],tot,n,m;
    21 double d[N],f[N][N],ans[N],sum,E[N*N*2];
    22 inline void add(int u,int v){
    23     ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
    24 }
    25 void gauss(){
    26     for(int i=1;i<n;++i){
    27         int k=i;
    28         for(int j=i+1;j<n;++j)
    29         if(fabs(f[k][i])<fabs(f[j][i])) k=j;
    30         if(k!=i) swap(f[i],f[k]);
    31         double div=f[i][i];
    32         for(int j=i;j<=n;++j) f[i][j]/=div;
    33         for(int j=i+1;j<n;++j){
    34             double t=f[j][i];
    35             for(int k=1;k<n+1;++k)
    36             f[j][k]-=t*f[i][k];
    37         }
    38     }
    39     for(int i=n-1;i;--i){
    40         for(int j=i+1;j<n;++j)
    41         f[i][n]-=f[i][j]*ans[j];
    42         ans[i]=f[i][n]/f[i][i];
    43     }
    44 }
    45 int main(){
    46 //    freopen("testdata.in","r",stdin);
    47     n=read(),m=read();
    48     for(int i=1,u,v;i<=m;++i){
    49         u=read(),v=read();add(u,v),add(v,u);
    50         d[u]+=1,d[v]+=1;
    51         from[i]=u,to[i]=v;
    52     }
    53     for(int i=1;i<n;++i){
    54         f[i][i]=1.0;
    55         for(int j=head[i];j;j=Next[j])
    56         if(ver[j]!=n)
    57         f[i][ver[j]]=-1/d[ver[j]];
    58     }
    59     f[1][n]=1;
    60     gauss();
    61     for(int i=1;i<=m;++i)
    62     E[i]=ans[from[i]]/d[from[i]]+ans[to[i]]/d[to[i]];
    63     sort(E+1,E+1+m);
    64     for(int i=1;i<=m;++i) sum+=E[i]*(m-i+1.0);
    65     printf("%.3lf
    ",sum);
    66     return 0;
    67 }
  • 相关阅读:
    wireshark无法捕获无线网卡数据解决办法(failed to set hardware filter to promiscuous mode)
    用PHP检测用户是用手机(Mobile)还是电脑(PC)访问网站
    一次.net Socket UDP编程的10万客户端测试记录
    对象复制
    c#中volatile关键字的作用
    C#操作XML
    ASP.NET AJAX
    C#操作XMl2
    SQLServer 存储过程中不拼接SQL字符串实现多条件查询
    ASP.NET刷新页面的六种方法20081111 22:04asp.net页面刷新重是有问题,收藏几种方法挺有用的.
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9740357.html
Copyright © 2011-2022 走看看