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 }
  • 相关阅读:
    我的软件工程课目标
    软件工程课程的建议
    结对编程学习fault、error、failure三种状态
    结对编程项目的过程记录与收获
    “结对编程”之我见
    关于问卷调查
    我的软件工程课目标
    软件工程课程建议
    结对编程2
    结对编程之四则运算
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5535720.html
Copyright © 2011-2022 走看看