zoukankan      html  css  js  c++  java
  • BZOJ 3143 游走(高斯消元)

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

    思路:显然,需要求出每条边的期望经过次数,然后排序贪心赋值即可,但是每条边的期望经过次数是什么呢?

    是 E(e)=E(u)/D(u) + E(v)/D(v) (u,v∈e)

    所以做法就是先求出每个点的期望经过次数,还有,就是对于第n个点,它的期望在最后统计的时候要看做0,因为到了n点就不会再出来了。

     1 #include<algorithm>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<iostream>
     6 struct edge{
     7     int u,v;
     8     double w;
     9 }e[500005];
    10 int n,m,du[500005],go[1005][1005];
    11 double a[1010][1010],p[500005];
    12 bool Cmp(edge q,edge w){
    13     return q.w>w.w;
    14 }
    15 void gauss(){
    16     int to,now=1;
    17     for (int i=1;i<=n;i++){
    18         for (to=now;to<=n;to++) if (a[to][i]!=0) break;
    19         if (to>n) continue;
    20         if (to!=now) for (int j=1;j<=n+1;j++) std::swap(a[now][j],a[to][j]);
    21         double t=a[now][i];
    22         for (int j=1;j<=n+1;j++) a[now][j]/=t;
    23         for (int j=1;j<=n;j++)
    24          if (j!=now){
    25                 t=a[j][i];
    26                 for (int k=1;k<=n+1;k++)
    27                  a[j][k]-=t*a[now][k];
    28         }
    29         now++;
    30     }
    31 }
    32 int main(){
    33     scanf("%d%d",&n,&m);
    34     int tot=0;
    35     for (int i=1;i<=m;i++){
    36         int x,y;
    37         scanf("%d%d",&x,&y);
    38         if (x==y) continue;
    39         e[++tot].u=x;e[tot].v=y;
    40         go[x][++go[x][0]]=y;
    41         go[y][++go[y][0]]=x;
    42         du[e[tot].u]++;
    43         du[e[tot].v]++;
    44     }
    45     m=tot;
    46     for (int i=1;i<n;i++) a[i][i]=1;
    47     for (int i=1;i<n;i++){
    48         for (int j=1;j<=go[i][0];j++){
    49             int t=go[i][j];
    50             if (t==n) continue;
    51             a[i][t]-=1.0/du[t];
    52         }
    53     }
    54     n--;
    55     a[1][n+1]=1;
    56     gauss();
    57     for (int i=1;i<=n;i++) p[i]=a[i][n+1];
    58     for (int i=1;i<=m;i++)
    59      e[i].w=((double)p[e[i].u])/((double)du[e[i].u])+((double)p[e[i].v])/((double)du[e[i].v]);
    60     std::sort(e+1,e+1+m,Cmp);
    61     double ans=0;
    62     for (int i=1;i<=m;i++) ans+=e[i].w*i;
    63     printf("%.3f
    ",ans);
    64 }
  • 相关阅读:
    jQuery EasyUI API 中文文档 可调整尺寸
    jQuery EasyUI API 中文文档 链接按钮(LinkButton)
    jQuery EasyUI API 中文文档 手风琴(Accordion)
    jQuery EasyUI API 中文文档 表单(Form)
    jQuery EasyUI API 中文文档 组合(Combo)
    jQuery EasyUI API 中文文档 布局(Layout)
    jQuery EasyUI API 中文文档 拆分按钮(SplitButton)
    jQuery EasyUI API 中文文档 菜单按钮(MenuButton)
    jQuery EasyUI API 中文文档 搜索框
    jQuery EasyUI API 中文文档 验证框(ValidateBox)
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5535720.html
Copyright © 2011-2022 走看看