[BZOJ1778] 期望+高斯消元

[BZOJ1778]

题意

给你一张 n n n个点 m m m条边的无向图,最开始有一颗炸弹在一号节点,它有 p q \frac{p}{q} qp​的概率爆炸,如果没有爆炸,它会等概率的移动到另一个与当前节点相连的点,问炸弹分别在每个点爆炸的概率。

思路

考虑一维的向量矩阵 A A A,第 i i i位表示炸弹停在 i i i点的概率是 A i A_{i} Ai,那么初始时炸弹停在 1 1 1号节点 A = ( 1 , 0 , 0 , . . . , 0 , 0 ) A=(1,0,0,...,0,0) A=(1,0,0,...,0,0),考虑如何转移,设 D i D_{i} Di表示 i i i点的度数,那么有 A i A_{i} Ai= ∑ ( 1 − p q ) ∗ 1 D j ∗ A j \sum(1-\frac{p}{q})*\frac{1}{D_{j}}*A_{j} (1qp)Dj1Aj j j j i i i能到达的点)。那么可以建立一个 n ∗ n n*n nn的矩阵 B B B B i , j = ( 1 − p q ) ∗ 1 D j B_{i,j}=(1-\frac{p}{q})*\frac{1}{D_{j}} Bi,j=(1qp)Dj1,那么最终答案矩阵 a n s ans ans= ( A + A ⋅ B + A ⋅ B ⋅ B + . . . + A ⋅ B o o ) (A+A\cdot B+A\cdot B\cdot B+...+A\cdot B^{oo}) (A+AB+ABB+...+ABoo),等比数列求和得到 a n s = A I − B ans=\frac{A}{I-B} ans=IBA a n s ⋅ ( I − B ) = A ans\cdot (I-B)=A ans(IB)=A,直接高斯消元即可。

Code

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
using namespace std;
const double eps=1e-15;
const int N=500;
struct node{int y,n;}e[100010];
int lin[100010],d[N],len=0,n,m,x,y;
double a[N][N],ans[N],p,q;
void read(int x,int y)
{e[++len].y=y,e[len].n=lin[x],lin[x]=len;}
bool gauss(){
 rep(i,1,n){
  int k=i;
  rep(j,i+1,n)if(fabs(a[j][i])>fabs(a[k][i]))k=j;
  if(fabs(a[k][i])<=eps)return 0;
  if(k!=i)swap(a[k],a[i]);
  double tmp=a[i][i];
  rep(j,i,n+1)a[i][j]/=tmp;
  rep(j,i+1,n){
   tmp=a[j][i];
   rep(k,i,n+1)a[j][k]-=a[i][k]*tmp;
  }
 }
 ans[n]=a[n][n+1];
 per(i,n-1,1){
  ans[i]=a[i][n+1];
  rep(j,i+1,n){
   ans[i]-=a[i][j]*ans[j];
  }
 }return 1;
}
int main(){
 scanf("%d%d%lf%lf",&n,&m,&p,&q);p/=q;
 rep(i,1,m){
  scanf("%d%d",&x,&y);
  read(x,y);read(y,x);
  d[x]++,d[y]++;
 }
 a[1][n+1]=1;
 rep(x,1,n){
  a[x][x]=1;
  for(int i=lin[x];i;i=e[i].n){
   int y=e[i].y;
   a[x][y]=-(1.0-p)/d[y];
  }
 }
 gauss();
 rep(i,1,n)printf("%.9lf\n",ans[i]*p+eps);
 return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值