牛客训练赛n的约数题解
题外话
艹他奶奶的,我都快写完了忘记保存了!
正文
很好的题目,让我的大脑旋转
容易想到将x1-xn设为在1-n号点爆炸的概率,mapp[i][j]设为从i到j不爆炸转移的概率。
错误方法
代码:
for(int i=1;i<=m;i++){
mapp[u[i]][v[i]]=(1-p/q)/du[v[i]];
mapp[v[i]][u[i]]=(1-p/q)/du[u[i]];
}
for(int i=1;i<=n;i++){
mapp[i][i]=1;
}
mapp[1][n+1]=(double)p/q;
此次省略高斯消元模板
好,直接交!
好,WA0分!
好,不做了!水犇犇去啦!
那么,为啥不对呢?
非常恶心的细节处理
仔细想一想,你用爆炸的概率 * 不爆炸转移的概率是啥?啥也不是好吧!
正常来讲,应该用不爆炸的概率 * 转移成功的概率。
这时,思考一下不爆炸的概率和爆炸的概率的关系。
显然,不爆炸概率=1-爆炸概率
AC code
#include<bits/stdc++.h>
using namespace std;
double mapp[310][310],p,q;
int u[44855],v[44855],du[44855];
int n,m;
int main(){
cin>>n>>m>>p>>q;
for(int i=1;i<=m;i++){
cin>>u[i]>>v[i];
du[u[i]]++;
du[v[i]]++;
}
for(int i=1;i<=m;i++){
mapp[u[i]][v[i]]=((double)p/q-1)/du[v[i]];
mapp[v[i]][u[i]]=((double)p/q-1)/du[u[i]];
}
for(int i=1;i<=n;i++){
mapp[i][i]=1;
}
mapp[1][n+1]=(double)p/q;
int r;
for(int i=1;i<=n;i++){
r=i;
for(int j=i;j<=n;j++){
if(fabs(mapp[r][i])<fabs(mapp[j][i])){
r=j;
}
}
swap(mapp[i],mapp[r]);
double t=mapp[i][i];
for(int j=i+1;j<=n;j++){
t=mapp[j][i]/mapp[i][i];
for(int k=i;k<=n+1;k++){
mapp[j][k]-=mapp[i][k]*t;
}
}
}
for(int i=n;i>=1;i--){
for(int j=i+1;j<=n;j++){
mapp[i][n+1]-=mapp[i][j]*mapp[j][n+1];
}
mapp[i][n+1]/=mapp[i][i];
}
for(int i=1;i<=n;i++){
printf("%.9lf\n",(mapp[i][n+1]));
}
}

浙公网安备 33010602011771号