【Bzoj3270】博物馆

感觉自己的概率与期望不是非常熟练,所以练习一下。

首先,这道题用二元组(x,y)表示状态,表示当前A走到x,B走到y

然后可以列出n*n个方程

高斯消元即可,时间复杂度O(n^6)

P.S. 注意几个赋值为-1的地方

 1 #include<cstdio>
 2 #include<vector>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=23;
 7 const double eps=1e-9;
 8 int n,m,u,v,s,t,d[maxn],size;
 9 double p[maxn],out[maxn],b[410][410],ans[410];
10 vector <int> a[maxn];
11 int id(int x,int y){
12     return n*(x-1)+y;
13 }
14 void build(int x,int y){
15     b[id(x,y)][id(x,y)]=-1;
16     for (int i=0; i<a[x].size(); i++)
17         for (int j=0; j<a[y].size(); j++) {
18             int uu=a[x][i]; int vv=a[y][j];
19             if (uu!=vv) {
20                 if (uu==x && vv==y) b[id(x,y)][id(uu,vv)]+=p[x]*p[y];
21                 else if (uu==x && vv!=y) b[id(x,y)][id(uu,vv)]+=p[x]*out[vv];
22                 else if (uu!=x && vv==y) b[id(x,y)][id(uu,vv)]+=p[y]*out[uu];
23                 else if (uu!=x && vv!=y) b[id(x,y)][id(uu,vv)]+=out[uu]*out[vv];
24             }
25         }
26 }
27 void gauss(){
28     for (int i=1; i<size; i++) {
29         int num=i;
30         for (int j=i+1; j<=size; j++) if (fabs(b[j][i])>fabs(b[num][i])) num=j;
31         if (num!=i) for (int j=1; j<=size+1; j++) swap(b[num][j],b[i][j]);
32         for (int j=i+1; j<=size; j++) {
33             if (fabs(b[j][i]<eps)) continue;
34             double tt=b[j][i]/b[i][i];
35             for (int k=1; k<=size+1; k++) b[j][k]-=tt*b[i][k];
36         }
37     }
38     for (int i=size; i>0; i--) {
39         double tt=1.00*b[i][size+1];
40         for (int j=i+1; j<=size; j++) tt-=1.00*ans[j]*b[i][j];
41         ans[i]=tt/b[i][i];
42     }
43 }
44 int main(){
45     scanf("%d%d%d%d",&n,&m,&s,&t);
46     size=n*n;
47     b[id(s,t)][size+1]=-1;
48     for (int i=1; i<=m; i++) {
49         scanf("%d%d",&u,&v);
50         a[u].push_back(v);
51         a[v].push_back(u);
52         d[u]++; d[v]++;
53     }
54     for (int i=1; i<=n; i++) scanf("%lf",&p[i]);
55     for (int i=1; i<=n; i++) a[i].push_back(i),out[i]=(1.0-p[i])/(double)d[i];
56     for (int i=1; i<=n; i++)
57         for (int j=1; j<=n; j++) build(i,j);
58     gauss();
59     for (int i=1; i<=n; i++) printf("%.6lf ",fabs(ans[id(i,i)]));
60     printf("\n");
61     return 0;
62 }

 

posted @ 2017-05-02 17:02  MoerBlack  阅读(161)  评论(0编辑  收藏  举报