题意
有一天Petya和他的朋友Vasya在进行他们众多旅行中的一次旅行,他们决定去参观一座城堡博物馆。这座博物馆有着特别的样式。它包含由m条走廊连接的n间房间,并且满足可以从任何一间房间到任何一间别的房间。
两个人在博物馆里逛了一会儿后两人决定分头行动,去看各自感兴趣的艺术品。他们约定在下午六点到一间房间会合。然而他们忘记了一件重要的事:他们并没有选好在哪儿碰面。等时间到六点,他们开始在博物馆里到处乱跑来找到对方(他们没法给对方打电话因为电话漫游费是很贵的)
不过,尽管他们到处乱跑,但他们还没有看完足够的艺术品,因此他们每个人采取如下的行动方法:每一分钟做决定往哪里走,有Pi 的概率在这分钟内不去其他地方(即呆在房间不动),有1-Pi 的概率他会在相邻的房间中等可能的选择一间并沿着走廊过去。这里的i指的是当期所在房间的序号。在古代建造是一件花费非常大的事,因此每条走廊会连接两个不同的房间,并且任意两个房间至多被一条走廊连接。
两个男孩同时行动。由于走廊很暗,两人不可能在走廊碰面,不过他们可以从走廊的两个方向通行。(此外,两个男孩可以同时地穿过同一条走廊却不会相遇)两个男孩按照上述方法行动直到他们碰面为止。更进一步地说,当两个人在某个时刻选择前往同一间房间,那么他们就会在那个房间相遇。
两个男孩现在分别处在a,b两个房间,求两人在每间房间相遇的概率。
题解
我们考虑一下这个概率怎么求考虑到,如果我们知道了
f[i][j]f[i][j]表示第一个人在i,第二个人在j的期望出现次数
因为,期望=可能的步数i*以这个步数走到这个点数的概率
同时两个人只可能见面一次
所以期望出现次数就是我们所要求的概率
然后高斯消元一波就可以了
CODE
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int N=25;
const long double eps=1e-10;
int n,m;
int a,b;
double d[N];
double p[N];
int P (int x,int y){return (x-1)*n+y;}
struct qq
{
int x,y,last;
}e[N*N];int num,last[N];
void init (int x,int y)
{
num++;
e[num].x=x;e[num].y=y;
e[num].last=last[x];
last[x]=num;
}
double f[N*N][N*N];
void Gauss ()
{
int cnt=n*n;
for (int u=1;u<=cnt;u++)
{
if (f[u][u]<=eps)
{
for (int i=u;i<=cnt;i++)
{
if (f[i][u]>eps)
{
for (int j=1;j<=cnt+1;j++)
swap(f[u][j],f[i][j]);
break;
}
}
}
for (int i=u+1;i<=cnt;i++)
{
double j=f[i][u]/f[u][u];
for (int l=u;l<=cnt+1;l++)
f[i][l]=f[u][l]*j-f[i][l];
}
}
for (int u=cnt;u>=1;u--)
{
for (int i=u+1;i<=cnt;i++)
f[u][cnt+1]=f[u][cnt+1]-f[u][i]*f[i][cnt+1];
f[u][cnt+1]/=f[u][u];
}
}
int main()
{
num=0;memset(last,-1,sizeof(last));
scanf("%d%d%d%d",&n,&m,&a,&b);
for (int u=1;u<=m;u++)
{
int x,y;
scanf("%d%d",&x,&y);
d[x]=d[x]+1;d[y]=d[y]+1;
init(x,y);init(y,x);
}
for (int u=1;u<=n;u++) scanf("%lf",&p[u]);
for (int x1=1;x1<=n;x1++)//第一个人在哪个点
for (int x2=1;x2<=n;x2++)//第二个人在哪个点
{
int o=P(x1,x2);
//从o点出发
f[o][o]=-1;
if (x1!=x2) f[o][o]=f[o][o]+p[x1]*p[x2];
for (int u=last[x1];u!=-1;u=e[u].last)
{
int y=e[u].y;
//只有x1动
if (y==x2) continue;
f[o][P(y,x2)]=f[o][P(y,x2)]+p[x2]*(1-p[y])/d[y];
}
for (int u=last[x2];u!=-1;u=e[u].last)
{
int y=e[u].y;
if (y==x1) continue;
f[o][P(x1,y)]=f[o][P(x1,y)]+p[x1]*(1-p[y])/d[y];
}
for (int u=last[x1];u!=-1;u=e[u].last)
for (int i=last[x2];i!=-1;i=e[i].last)
{
int x=e[u].y,y=e[i].y;
if (x==y) continue;
f[o][P(x,y)]=f[o][P(x,y)]+(1-p[x])*(1-p[y])/d[x]/d[y];
}
/*for (int u=1;u<=n*n+1;u++) printf("%lf ",f[o][u]);
printf("\n");*/
}
f[P(a,b)][n*n+1]=-1;
/*for (int u=1;u<=n*n;u++)
{
for (int i=1;i<=n*n+1;i++)
printf("%lf ",f[u][i]);
printf("\n");
}*/
Gauss();
/* for (int u=1;u<=n*n;u++)
printf("%lf ",f[u][n*n+1]);*/
for (int u=1;u<=n;u++) printf("%.6lf ",f[P(u,u)][n*n+1]);
return 0;
}