zoukankan      html  css  js  c++  java
  • bzoj 3143 [Hnoi2013]游走 期望dp+高斯消元

    [Hnoi2013]游走

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 3394  Solved: 1493
    [Submit][Status][Discuss]

    Description

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

    Input

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

    Output

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

    Sample Input

    3 3
    2 3
    1 2
    1 3

    Sample Output

    3.333

    HINT

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

    Source

     
    题解:
      很好想的,列出期望方程,对于每个点,都有一个方程,n-1个方程
      解n-1个元,g[i]表示到达终点还需要多少。
      即可,发现一条边,只会在到u或者v产生贡献。
     1 #include<cmath>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 #define N 507
     7 #define M 250007
     8 
     9 using namespace std;
    10 
    11 int n,m;
    12 int U[M],V[M],d[N];
    13 double a[N][N],x[N],w[M],ans;
    14 
    15 void Gauss(int n,int m)
    16 {
    17     int i,j,k;
    18     for(i=1;i<m;i++)
    19     {
    20         for(k=i,j=i+1;j<=n;j++)if(fabs(a[k][i])<fabs(a[j][i]))k=j;
    21         if(i!=k)for(j=i;j<=m;j++)swap(a[i][j],a[k][j]);
    22         for(j=i+1;j<=n;j++)
    23         {
    24             double rate=a[j][i]/a[i][i];
    25             for(k=i;k<=m;k++)a[j][k]-=a[i][k]*rate;
    26         }
    27     }
    28     for(i=m-1;i;i--)
    29     {
    30         for(j=i+1;j<m;j++)a[i][m]-=a[i][j]*x[j];
    31         x[i]=a[i][m]/a[i][i];
    32     }
    33 }
    34 int main()
    35 {
    36     int i;
    37 
    38     scanf("%d%d",&n,&m);
    39     for(i=1;i<=m;i++)
    40     {
    41         scanf("%d%d",&U[i],&V[i]);
    42         d[U[i]]++,d[V[i]]++;
    43     }
    44     for(i=1;i<n;i++)a[i][i]=-1;
    45     for(i=1;i<=m;i++)
    46     {
    47         a[U[i]][V[i]]+=1.0/d[V[i]];
    48         a[V[i]][U[i]]+=1.0/d[U[i]];
    49     }
    50     for(i=1;i<=n;i++)a[n][i]=0;
    51     a[1][n+1]=-1,a[n][n]=1;
    52     Gauss(n,n+1);
    53     for(i=1;i<=m;i++)w[i]=x[U[i]]/d[U[i]]+x[V[i]]/d[V[i]];
    54     sort(w+1,w+m+1);
    55     for(i=1;i<=m;i++)ans+=(m-i+1)*w[i];
    56     printf("%.3lf
    ",ans);
    57 }
  • 相关阅读:
    八十五:redis之redis的事物、发布和订阅操作 (2019-11-18 22:54)
    八十四:redis之redis的集合、哈希操作
    八十三:redis之redis的字符串、过期时间、列表操作
    八十三:redis之redis的使用场景和安装
    八十二:memcached之python操作memcached
    八十一:memcached之telnet操作memcached
    八十:memcached之安装与参数
    MySQL篇之Navicat可视化工具
    MySQL数据库篇之多表查询
    MySQL数据库篇之单表查询
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8277350.html
Copyright © 2011-2022 走看看