3143. [HNOI2013] Walk [Gaussian Elimination]

Description

An undirected connected graph with vertices numbered from 1 to N and edges from 1 to M.
Small Z performs a random walk on the graph. Initially, small Z is at vertex No. 1. At each step, small Z randomly selects an edge of the current vertex with equal probability, and walks along this edge to the next vertex, obtaining equal to The numbered fraction of this edge. The walk ends when little Z reaches vertex N, and the total score is the sum of all the points obtained.
Now, please number these M edges so that the expected value of the total score obtained by small Z is the smallest.

Input

The first line is positive integers N and M, representing the number of vertices and edges of the graph, respectively, and each line of the next M lines is an integer u, v (1≤u, v≤N), indicating that there is a relationship between vertex u and vertex v one side. The input ensures that 30% of the data satisfies N≤10, 100% of the data satisfies 2≤N≤500 and is an undirected simple connected graph.

Output

Contains only one real number representing the smallest expected value with 3 decimal places.

Sample Input

3 3
2 3
1 2
1 3

Sample Output

3.333

HINT

Edge (1,2) is numbered 1 , edge (1,3) is numbered 2 , and edge (2,3) is numbered 3 .

 

 

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<algorithm>
 6 #define N (500+10)
 7 using namespace std;
 8 
 9 double eps=1e-10;
10 int dcmp(double x){if (fabs(x)<eps)return 0; return x>0?1:-1;}
11 
12 int Ind[N],head[N],num_edge;
13 int n,m,u,v,h,dis[N][N];
14 double ans[N],f[N][N],q[N*N];
15 
16 void Gauss()
17 {
18     for (int i=1; i<=n; ++i)
19     {
20         int num=i;
21         for (int j=i+1; j<=n; ++j)
22             if (dcmp(fabs(f[j][i])-fabs(f[num][i]))>0) num=j;
23         if (num!=i) for (int j=1; j<=n+1; ++j) swap(f[i][j],f[num][j]);
24         
25         for (int j=i+1; j<=n+1; ++j)
26             if (dcmp(f[j][i]))
27             {
28                 double t=f[j][i]/f[i][i];
29                 for (int k=i; k<=n+1; ++k)
30                     f[j][k]-=f[i][k]*t;
31             }
32     }
33     for (int i=n; i>=1; --i)
34     {
35         for (int j=i+1; j<=n; ++j) f[i][n+1]-=f[i][j]*ans[j];
36         ans[i]=f[i][n+1]/f[i][i];
37     }
38 }
39 
40 int main()
41 {
42     scanf("%d%d",&n,&m);
43     for (int i=1; i<=m; ++i)
44     {
45         scanf("%d%d",&u,&v);
46         dis[u][v]=dis[v][u]=1;
47         Ind[u]++; Ind[v]++;
48     }
49     for (int i=1; i<=n; ++i)
50     {
51         f[i][i]=-1;
52         for (int j=1; j<=n; ++j)
53             if (dis[i][j])
54                 f[i][j]=(double)1/Ind[j];
55     }
56     f[1][n+1]=-1;
57     for (int i=1; i<n; ++i) f[n][i]=0;
58     Gauss();
59     for (int i=1; i<=n; ++i)
60         for (int j=i+1; j<=n; ++j)
61             if (dis[i][j])
62                 q[++h]=ans[i]/Ind[i]+ans[j]/Ind[j];
63     sort(q+1,q+h+1);
64     double Ans=0;
65     for (int i=1; i<=m; ++i)
66         Ans+=i*q[m-i+1];
67     printf("%.3lf",Ans);
68 }

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325016188&siteId=291194637