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) 编辑 收藏 举报