首先高斯消元解出每个点被走到的概率

注意到这里走到$n$就停下来了,所以$P(n) = 0$

解出来以后,给每条边$(u, v)$赋边权$P(u) + P(v)$即可,然后直接贪心

 

 1 /**************************************************************
 2     Problem: 3143
 3     User: rausen
 4     Language: C++
 5     Result: Accepted
 6     Time:680 ms
 7     Memory:6792 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #include <cmath>
12 #include <algorithm>
13  
14 using namespace std;
15 typedef double lf;
16 const int N = 505;
17 const int M = N * N;
18 const lf eps = 1e-7;
19  
20 int read();
21  
22 int n, m, tot;
23 int deg[N];
24 lf a[N][N], ans[N], w[M];
25 lf Ans;
26  
27 struct edge {
28     int x, y;
29 } E[M];
30  
31 inline void Add_Edges(int x, int y) {
32     E[++tot].x = x, E[tot].y = y;
33     a[x][y] = a[y][x] = -1.0;
34     ++deg[x], ++deg[y];
35 }
36  
37 void gauss(int n) {
38     int i, j, k;
39     lf tmp;
40     for (i = 1; i <= n; ++i) {
41         for (k = i, j = i + 1; j <= n; ++j)
42             if (fabs(a[j][i]) > fabs(a[k][i])) k = j;
43         if (fabs(a[k][i]) < eps) continue;
44         for (j = i; j <= n + 1; ++j) swap(a[i][j], a[k][j]);
45         for (k = i + 1; k <= n; ++k)
46             for (tmp = -a[k][i] / a[i][i], j = i; j <= n + 1; ++j)
47                 a[k][j] += a[i][j] * tmp;
48     }
49     for (i = n; i; --i) {
50         for (j = i + 1; j <= n; ++j)
51             a[i][n + 1] -= a[i][j] * ans[j];
52         ans[i] = a[i][n + 1] / a[i][i];
53     }
54 }
55  
56 int main() {
57     int i, j;
58     n = read(), m = read();
59     for (i = 1; i <= m; ++i)
60         Add_Edges(read(), read());
61     for (i = 1; i < n; ++i) {
62         for (j = 1; j < n; ++j)
63             if (deg[j]) a[i][j] = a[i][j] / deg[j];
64         a[i][i] = 1, a[i][n] = 0;
65     }
66     a[1][n] = 1;
67     gauss(n - 1);
68     for (i = 1; i <= n; ++i)
69         if (deg[i]) ans[i] /= deg[i];
70     for (i = 1; i <= m; ++i)
71         w[i] = ans[E[i].x] + ans[E[i].y];
72     sort(w + 1, w + m + 1);
73     for (i = 1; i <= m; ++i) Ans += w[i] * (m - i + 1);
74     printf("%.3lf\n", Ans);
75     return 0;
76 }
77  
78 inline int read() {
79     static int x;
80     static char ch;
81     x = 0, ch = getchar();
82     while (ch < '0' || '9' < ch)
83         ch = getchar();
84     while ('0' <= ch && ch <= '9') {
85         x = x * 10 + ch - '0';
86         ch = getchar();
87     }
88     return x;
89 }
View Code

 

posted on 2015-05-25 21:11  Xs酱~  阅读(637)  评论(0编辑  收藏  举报