题意
一开始两个人分别站在ss和,一个人在每个点有pp的概率不动,或者等概率地随机走到一个相邻的点
求两个人在每个点相遇的概率
题解
感觉是游走的加强版来着
设
didi表示点ii的点度,表示在ii点不动的概率
表示第一个人在ii点,第二个人在点的状态编号
f[i]f[i]达到表示ii状态的期望步数,
我们枚举一个点xx表示上一步第一个所在的位置,表示第二个人的
当然x≠yx≠y,因为相等就已经停下了,不会对其他状态产生贡献了
可以很容易想到有44种转移
同样这个转移是存在环的,所以需要高斯消元,列式方法和上一题一样(同样的套路)
初值G[as,t][n2+1]=1G[as,t][n2+1]=1(因为f[as,t]=1+∑…f[as,t]=1+∑…)
#include<bits/stdc++.h>
#define fp(i,a,b) for(register int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(register int i=a,I=b-1;i>I;--i)
#define go(u) for(register int i=fi[u],v=e[i].to;i;v=e[i=e[i].nx].to)
#define file(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
const int N=405;
const double eps=1e-10;
typedef int arr[N];
typedef double d;
int n,m,s,t,Cnt;arr dg,a[N],mp[N];d p[N],ans[N],G[N][N];
inline int cmp(const d&x){return fabs(x)<eps?0:(x<0?-1:1);}
inline void Gauss(int n){
int mx;d t;
fp(i,1,n){mx=i;
fp(j,i,n)if(cmp(G[mx][i]-G[j][i]))mx=i;
if(mx^i)fp(j,i,n+1)swap(a[i][j],a[mx][j]);
fp(j,i+1,n)if(cmp(G[j][i])){
t=G[j][i]/G[i][i];
fp(k,i,n+1)G[j][k]-=t*G[i][k];
}
}
fd(i,n,1){
fp(j,i+1,n)G[i][n+1]-=ans[j]*G[i][j];
ans[i]=G[i][n+1]/G[i][i];
}
}
int main(){
#ifndef ONLINE_JUDGE
file("s");
#endif
scanf("%d%d%d%d",&n,&m,&s,&t);
while(m--){
int u,v;scanf("%d%d",&u,&v);
mp[u][v]=mp[v][u]=1;++dg[u],++dg[v];
}
fp(i,1,n)scanf("%lf",p+i),mp[i][i]=1;
fp(i,1,n)fp(j,1,n)a[i][j]=++Cnt;
G[a[s][t]][Cnt+1]=1;
fp(i,1,n)fp(j,1,n){
int pos=a[i][j];G[pos][pos]=1;
fp(x,1,n)if(mp[i][x])fp(y,1,n)if(mp[j][y]&&x^y){
d p1,p2;
if(i==x)p1=p[i];else p1=(1.0-p[x])/dg[x];
if(j==y)p2=p[j];else p2=(1.0-p[y])/dg[y];
G[pos][a[x][y]]+=-p1*p2;
}
}
Gauss(Cnt);
fp(i,1,n)printf("%.6lf ",ans[a[i][i]]);
return 0;
}

解决两人在图中随机游走并求相遇概率的问题,通过建立状态方程并使用高斯消元法求解。
513

被折叠的 条评论
为什么被折叠?



