bzoj 3143: [Hnoi2013]游走

高斯消元 对于边可能很多,那我们计录点的期望次数就行了。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<queue>
 7 #include<algorithm>
 8 #include<vector>
 9 #define M 1009
10 #define EPS 1e-10
11 #define MO 19650827
12 #define ll long long
13 using namespace std;
14 ll read()
15 {
16     char ch=getchar();
17     ll x=0,f=1;
18     for(;ch<'0'||ch>'9';ch=getchar())
19         if(ch=='-')
20           f=-1;
21     for(;ch>='0'&&ch<='9';ch=getchar())
22         x=x*10+ch-'0';
23     return x*f;
24 }
25 int n,m,du[M],u[M*M],v[M*M];
26 double a[M][M],b[M*M];
27 void gao()
28 {
29   for(int i=1;i<=n;i++)
30     {
31       int k=i;
32       for(;k<=n&&!a[k][i];k++);
33       if(!a[k][i])
34         break;
35       for(int j=1;j<=n+1;j++)
36         swap(a[k][j],a[i][j]);
37       double a1=a[i][i];
38       for(int j=1;j<=n+1;j++)
39         a[i][j]/=a1;
40       for(int j=1;j<=n;j++)
41         if(i!=j&&a[j][i])
42           {
43             a1=a[j][i];
44             for(int k=1;k<=n+1;k++)
45               a[j][k]-=a[i][k]*a1;
46           }
47     }
48 }
49 int main()
50 {
51    n=read();
52    m=read();
53    for(int i=1;i<=m;i++)
54      {
55        u[i]=read();
56        v[i]=read();
57        du[u[i]]++;
58        du[v[i]]++;
59        a[u[i]][v[i]]=-1;
60        a[v[i]][u[i]]=-1;
61      }
62    for(int i=1;i<n;i++)
63      for(int j=1;j<=n;j++)
64        a[i][j]/=du[j];
65    for(int i=1;i<=n;i++)
66      a[n][i]=0;
67    a[1][n+1]=1;
68    for(int i=1;i<=n;i++)
69      a[i][i]=1;
70    gao();
71    for(int i=1;i<=m;i++)
72      {
73          b[i]+=a[u[i]][n+1]/du[u[i]];
74          b[i]+=a[v[i]][n+1]/du[v[i]];
75      }
76    sort(b+1,b+m+1);
77    double ans=0;
78    for(int i=1;i<=m;i++)
79      ans+=b[i]*(m-i+1);
80    printf("%.3lf\n",ans);
81    return 0;
82 }

 

posted @ 2016-07-08 21:46  xiw5  阅读(141)  评论(0编辑  收藏  举报