bzoj 3143 [Hnoi2013]游走 期望dp+高斯消元

Posted Kaiser

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n",ans);
57 }

 

以上是关于bzoj 3143 [Hnoi2013]游走 期望dp+高斯消元的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 3143: [Hnoi2013]游走

●BZOJ 3143 [Hnoi2013]游走

bzoj 3143 [Hnoi2013]游走 期望dp+高斯消元

[BZOJ 3143][Hnoi2013]游走(高斯消元+期望)

BZOJ3143: [Hnoi2013]游走 期望+高斯消元

[BZOJ3143][HNOI2013]游走