山东济南彤昌机械科技有限公司 山东济南江鹏工贸游有限公司

bzoj 3270 博物馆(高斯消元)

 

【题意】

 

    两人起始在s,t点,一人pi概率选择留在i点或等概率移动,问两人在每个房间相遇的概率。

 

【思路】

 

    把两个合并为一个状态,(a,b)表示两人所处的状态,设f[i]为两人处于i状态的概率。则有转移式:

        f[(a,b)]=p[a]*a[b]*f[(a,b)]+((1-p[av])/du[av])*p[b]*f[(av,b)]+((1-p[bv]))/du[bv]*p[a]*f[(a,bv)]+ ((1-p[av])/du[av])* ((1-p[bv])/du[bv])*f[(av,bv)]

        f[(s,t)]=1+上面的

    特殊的,当a==b时,式子为f[(a,a)]=1。

 

【代码】

 

 1 #include<set>
 2 #include<cmath>
 3 #include<queue>
 4 #include<vector>
 5 #include<cstdio>
 6 #include<cstring>
 7 #include<iostream>
 8 #include<algorithm>
 9 #define id(i,j) ((i-1)*n+j)
10 #define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
11 #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
12 using namespace std;
13 
14 typedef long long ll;
15 const int N = 30;
16 const int M = N*N;
17 
18 ll read() {
19     char c=getchar();
20     ll f=1,x=0;
21     while(!isdigit(c)) {
22         if(c=='-') f=-1; c=getchar();
23     }
24     while(isdigit(c))
25         x=x*10+c-'0',c=getchar();
26     return x*f;
27 }
28 
29 struct Edge {
30     int v,nxt;
31 }e[M];
32 int en=1,front[N];
33 void adde(int u,int v) 
34 {
35     e[++en]=(Edge){v,front[u]}; front[u]=en;
36 }
37 
38 int n,m,S,T,du[M];
39 double a[M][M],p[M];
40 
41 void gause(int n)
42 {
43     for(int i=1;i<=n;i++) 
44     {
45         int r=i;
46         for(int j=i+1;j<=n;j++)
47             if(fabs(a[j][i])>fabs(a[r][i])) r=j;
48         for(int j=1;j<=n+1;j++)    swap(a[i][j],a[r][j]);
49         for(int j=n+1;j;j--)
50             for(int k=i+1;k<=n;k++)
51                 a[k][j]-=a[k][i]/a[i][i]*a[i][j];
52     }
53     for(int i=n;i;i--) 
54     {
55         for(int j=i+1;j<=n;j++)
56             a[i][n+1]-=a[i][j]*a[j][n+1];
57         a[i][n+1]/=a[i][i];
58     }
59 }
60 
61 void get_a(int s,int t) 
62 {
63     int now=id(s,t);
64     a[now][now]-=1;
65     trav(s,i) trav(t,j)
66     {
67         if(e[i].v==e[j].v) continue;
68         int u=e[i].v,v=e[j].v;
69         int nxt=id(u,v);
70         double outu=(1-p[u])/du[u],outv=(1-p[v])/du[v];
71         if(u==s&&v==t) a[now][nxt]+=p[u]*p[v];
72         else if(u==s) a[now][nxt]+=p[u]*outv;
73         else if(v==t) a[now][nxt]+=p[v]*outu;
74         else a[now][nxt]+=outu*outv;
75     }
76 }
77 
78 int main()
79 {
80 //    freopen("in.in","r",stdin);
81 //    freopen("out.out","w",stdout);
82     n=read(),m=read(),S=read(),T=read();
83     int u,v;
84     FOR(i,1,m) {
85         u=read(),v=read();
86         adde(u,v),adde(v,u);
87         du[u]++,du[v]++;
88     }
89     FOR(i,1,n) scanf("%lf",&p[i]),adde(i,i);
90     FOR(i,1,n) FOR(j,1,n)
91         get_a(i,j);
92     a[id(S,T)][n*n+1]=-1;
93     gause(n*n);
94     FOR(i,1,n) 
95         printf("%.6lf ",a[id(i,i)][n*n+1]);
96     return 0;
97 }

 

posted on 2016-03-31 19:41  hahalidaxin  阅读(304)  评论(0编辑  收藏  举报