博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CF446D DZY Loves Games
阅读量:6193 次
发布时间:2019-06-21

本文共 2809 字,大约阅读时间需要 9 分钟。

 

高斯消元好题

如果暴力地,令f[i][k]表示到i,有k条命的概率,就没法做了。

转化题意

生命取决于经过陷阱的个数

把这个看成一步

所以考虑从一个陷阱到另一个陷阱,不经过其他陷阱的概率p[i][j]

当然1出发到其他陷阱的概率也要得到。

然后相当于有一个新图,

从1出发,走k-1步恰好到n的概率

 

暴力方法:

枚举一个出发点s,

则$P_x=\sum_{v&&v!=trap}P_v/deg_v+P(x is a start)$

特别地,v是s也可以转移(虽然s可能是陷阱,但是是出发点)

O(n^4)

 

考虑优化

其实所有的系数都是一样的。只是常数项不一样。即$P(x is a start)$不同。

什么,你说对于某些s是trap,但是作为出发点可以转移这里不同的s条件不同?

我们可以枚举s的出点v,直接把v作为出发点,概率是1/deg(s)

 

所以,我们可以把常数项扔到等号后面,堆成长度为陷阱数量的向量。

一起带着消即可。

 

#include
#define numb (ch^'0')#define il inline#define reg register intusing namespace std;typedef long long ll;template
il void rd(T &x){ x=0;char ch;bool fl=false; while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true); for(x=numb;isdigit(ch=getchar());x=x*10+numb); (fl==true)&&(x=-x);}template
il void prt(T a[],int st,int nd){ for(reg i=st;i<=nd;++i) cout<
<<" ";cout<
fabs(f[id][i])) id=j; } if(id!=i){ for(reg j=i;j<=n+c;++j){ swap(f[i][j],f[id][j]); } } for(reg j=i+1;j<=n;++j){ if(fabs(f[j][i])>0){ double lp=f[j][i]/f[i][i]; for(reg k=i;k<=n+c;++k){ f[j][k]-=f[i][k]*lp; } } } } if(typ!=1){ for(reg i=n;i>=1;--i){ for(reg j=i+1;j<=n;++j){ if(fabs(f[i][j])>0){ for(reg k=n+1;k<=n+c;++k){ f[i][k]-=f[i][j]*p[k-n][j]; } } } for(reg k=n+1;k<=n+c;++k){ p[k-n][i]=f[i][k]/f[i][i]; } } }else{// for(reg i=1;i<=n;++i){// for(reg j=1;j<=n+c;++j){// cout<
<<" ";// }cout<
=1;--i){ for(reg j=i+1;j<=n;++j){ if(fabs(f[i][j])>0){ f[i][n+1]-=f[i][j]*p[0][j]; } } p[0][i]=f[i][n+1]/f[i][i]; } }}struct tr{ double a[105][105]; tr(){memset(a,0,sizeof a);} void init(){ for(reg k=0;k<=num;++k){ a[k][k]=1.00; } } tr friend operator *(const tr &a,const tr &b){ tr c; for(reg k=0;k<=num;++k){ for(reg i=0;i<=num;++i){ for(reg j=0;j<=num;++j){ c.a[i][j]+=a.a[i][k]*b.a[k][j]; } } } return c; }}S,B;tr qm(tr B,int y){ tr ret;ret.init(); while(y){ if(y&1) ret=ret*B; B=B*B; y>>=1; } return ret;}int main(){ rd(n);rd(m);rd(T); for(reg i=1;i<=n;++i){ rd(has[i]); if(has[i]) mem[++num]=i,id[i]=num; } int x,y; for(reg i=1;i<=m;++i){ rd(x);rd(y); ++du[x];++du[y]; ++con[x][y];++con[y][x]; } for(reg i=1;i<=n;++i){ f[i][i]=1.000; for(reg j=1;j<=n;++j){ if(j==i) continue; if(!has[j]&&con[i][j]){ f[i][j]=-(double)con[i][j]/du[j]; } } if(i==1) f[i][n+1]=1.00; } guass(1,1); // for(reg i=1;i<=num;++i){// cout<<" memi "<
<<" : "<
<<" "<
<

只关心生命值多少

题意转化!变成新图!

系数相同,带着常数一起消除!

 

转载于:https://www.cnblogs.com/Miracevin/p/11061965.html

你可能感兴趣的文章