bzoj 3143 随机游走

 

题意:

  给一个简单无向图,一个人从1号节点开始随机游走(即以相同概率走向与它相邻的点),走到n便停止,问每条边期望走的步数.

 

首先求出每个点期望走到的次数,每条边自然是从它的两个端点走来.

 

 1 /**************************************************************
 2     Problem: 3143
 3     User: idy002
 4     Language: C++
 5     Result: Accepted
 6     Time:736 ms
 7     Memory:9956 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #include <cmath>
12 #include <algorithm>
13 #define N 510
14 #define M N*N
15 using namespace std;
16  
17 int n, m;
18 int head[N], dest[M], next[M], etot;
19 int dgr[N], uu[M], vv[M], qu[M];
20 double ww[M];
21 double a[N][N];
22  
23 void adde( int u, int v ) {
24     etot++;
25     dest[etot] = v;
26     next[etot] = head[u];
27     head[u] = etot;
28 }
29 void gauss() {
30     int i, j, k;
31     for( i=1; i<=n; i++ ) {
32         j=i;
33         for( k=i+1; k<=n; k++ ) 
34             if( fabs(a[k][i])>fabs(a[j][i]) ) j=k;
35         for( k=i; k<=n+1; k++ )
36             swap( a[j][k], a[i][k] );
37         for( j=i+1; j<=n; j++ ) {
38             double r = a[j][i]/a[i][i];
39             for( k=i; k<=n+1; k++ )
40                 a[j][k] -= a[i][k]*r;
41         }
42     }
43     for( int i=n; i>=1; i-- ) {
44         a[i][n+1] /= a[i][i];
45         a[i][i] = 1.0;
46         for( int j=i-1; j>=1; j-- ) {
47             a[j][n+1] -= a[j][i]*a[i][n+1];
48             a[j][i] = 0.0;
49         }
50     }
51 }
52 bool cmp( int a, int b ) {
53     return ww[a] > ww[b];
54 }
55 int main() {
56     scanf( "%d%d", &n, &m );
57     for( int i=1; i<=m; i++ ) {
58         scanf( "%d%d", uu+i, vv+i );
59         adde( uu[i], vv[i] );
60         adde( vv[i], uu[i] );
61         dgr[uu[i]]++;
62         dgr[vv[i]]++;
63     }
64     for( int i=1; i<=n; i++ )
65         a[i][i] = -1.0;
66     a[1][n+1] = -1;
67     for( int u=1; u<=n; u++ ) {
68         for( int t=head[u]; t; t=next[t] ) {
69             int v=dest[t];
70             if( v==n ) continue;
71             a[u][v] += 1.0/dgr[v];
72         }
73     }
74     gauss();
75     for( int i=1; i<=m; i++ ) {
76         int u=uu[i], v=vv[i];
77         if( u!=n ) ww[i]+=a[u][n+1]/dgr[u];
78         if( v!=n ) ww[i]+=a[v][n+1]/dgr[v];
79     }
80     for( int i=1; i<=m; i++ )
81         qu[i] = i;
82     sort( qu+1, qu+1+m, cmp );
83     double ans = 0.0;
84     for( int i=1; i<=m; i++ )
85         ans += i * ww[qu[i]];
86     printf( "%.3lf\n", ans );
87 }
88 
View Code

 

posted @ 2015-06-16 15:35 idy002 阅读(...) 评论(...) 编辑 收藏