标签:scanf while splay ref tmp const push har 直接
有一张无向图,从一号节点开始,每次有\(\frac p q\) 的概率直接停在该点,否则就等概率地向连边的点走去
求停在每个点的概率
\(n \le 300\)
定义 \(f_i\) 为在 \(i\) 停下的概率
这个影响因素有哪些呢?
\(1.\) 在 \(1\) 号节点开始
\(2.\) 连边的点的出度
然后我们就有式子啦
(个人感觉挺好理解的)
把式子倒一下,搞成一个能高斯消元的矩阵求一下就OK了
最后注意第一个影响因素,\(a_{1,n+1}=1\)
#include<bits/stdc++.h>
using namespace std;
#define int long long
namespace yspm{
inline int read()
{
int res=0,f=1; char k;
while(!isdigit(k=getchar())) if(k==‘-‘) f=-1;
while(isdigit(k)) res=res*10+k-‘0‘,k=getchar();
return res*f;
}
const double eps=1e-13;
const int N=330;
double p,q,a[N][N],ans[N];
vector<int> vec[N];
int n,m,d[N];
signed main()
{
n=read(); m=read(); scanf("%lf%lf",&p,&q);
for(int i=1;i<=m;++i)
{
int x=read(),y=read();
vec[x].push_back(y);
vec[y].push_back(x);
d[x]++; d[y]++;
}
for(int i=1;i<=n;++i)
{
int siz=vec[i].size();
for(int j=0;j<siz;++j)
{
int y=vec[i][j];
a[i][y]+=-(1.0-p/q)/d[y];
}
} a[1][n+1]=1;
for(int i=1;i<=n;++i) a[i][i]=1;
for(int i=1;i<=n;++i)
{
int t=i;
for(int j=i+1;j<=n;++j) if(fabs(a[j][i])>fabs(a[t][i])) t=j; swap(a[t],a[i]);
double h=a[i][i];
if(fabs(h)<eps) continue;
for(int j=i;j<=n+1;++j) a[i][j]/=h;
for(int j=1;j<=n;++j)
{
if(j==i) continue;
double tmp=a[j][i];
for(int k=1;k<=n+1;++k) a[j][k]-=tmp*a[i][k];
}
}
for(int i=n;i>=1;--i)
{
for(int j=i+1;j<=n;++j)
{
a[i][n+1]-=ans[j]*a[i][j];
}ans[i]=a[i][n+1]/a[i][i];
}
for(int i=1;i<=n;++i) printf("%.10lf\n",ans[i]*p/q);
return 0;
}
}
signed main(){return yspm::main();}
其实不难,就是找到怎么建矩阵就好了
Luogu2973 [USACO10HOL]Driving Out the Piggies G
标签:scanf while splay ref tmp const push har 直接
原文地址:https://www.cnblogs.com/yspm/p/12742230.html