# 【复习】高斯消元解图上期望概率

BZOJ 1444 - [Jsoi2009]有趣的游戏
https://blog.sengxian.com/solutions/bzoj-1444

#include <cstdio>
#include <cstring>
#include <algorithm>
const int N=11;
char s[N*2];
int n,m,l,cnt,trans[N*N][N],id[N*N],fail[N*N],pos[N],queue[N*N],front,back;
double a[N*N][N*N],temp[N*N][N*N],pro[N];
inline void insert(int x){
int i,p=0;
for(i=1;i<=l;++i){
if(!trans[p][s[i]-'A'])trans[p][s[i]-'A']=++cnt;
p=trans[p][s[i]-'A'];
}
id[p]=x,pos[x]=p;
}
inline void Build(){
front=back=0;
queue[back++]=0;
int x,i;
while(front!=back){
x=queue[front++];
for(i=0;i<m;++i)
if(trans[x][i]){
queue[back++]=trans[x][i];
fail[trans[x][i]]=x?trans[fail[x]][i]:0;
}else
trans[x][i]=x?trans[fail[x]][i]:0;
}
}
inline void PF(){
register int i,j,k;
for(i=0;i<=cnt;++i)
for(j=0;j<=cnt;++j)
temp[i][j]=0;
for(i=0;i<=cnt;++i)
for(j=0;j<=cnt;++j)
for(k=0;k<=cnt;++k)
temp[i][j]+=a[i][k]*a[k][j];
for(i=0;i<=cnt;++i)
for(j=0;j<=cnt;++j)
a[i][j]=temp[i][j];
}
int main(){
//freopen("rio.txt","r",stdin);
scanf("%d%d%d",&n,&l,&m);
int i,j,x,y;
for(i=0;i<m;++i){
scanf("%d%d",&x,&y);
pro[i]=(double)x/y;
}
for(i=1;i<=n;++i){
scanf("%s",s+1);
insert(i);
}
Build();
for(i=0;i<=cnt;++i)
if(!id[i])
for(j=0;j<m;++j)
a[trans[i][j]][i]+=pro[j];
else
a[i][i]=1;
int T=50;
while(T--)PF();
for(i=1;i<=n;++i)
printf("%.2f\n",a[pos[i]][0]);
return 0;
}

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
const int N=11;
char s[N*2];
int n,m,l,cnt,trans[N*N][N],id[N*N],fail[N*N],pos[N],queue[N*N],front,back;
double a[N*N][N*N],pro[N],b[N*N];
inline void insert(int x){
int i,p=0;
for(i=1;i<=l;++i){
if(!trans[p][s[i]-'A'])trans[p][s[i]-'A']=++cnt;
p=trans[p][s[i]-'A'];
}
id[p]=x,pos[x]=p;
}
inline void Build(){
front=back=0;
queue[back++]=0;
int x,i;
while(front!=back){
x=queue[front++];
for(i=0;i<m;++i)
if(trans[x][i]){
queue[back++]=trans[x][i];
fail[trans[x][i]]=x?trans[fail[x]][i]:0;
}else
trans[x][i]=x?trans[fail[x]][i]:0;
}
}
inline void Gauss(){
int i,j,k,index;
double mul;
for(i=0;i<=cnt;++i){
index=i;
for(j=i+1;j<=cnt;++j)
if(std::fabs(a[j][i])>std::fabs(a[index][i]))
index=j;
if(std::fabs(a[index][i])==0)continue;
if(index!=i)
for(j=i;j<=cnt+1;++j)
std::swap(a[i][j],a[index][j]);
for(j=i+1;j<=cnt;++j){
mul=a[j][i]/a[i][i];
for(k=i;k<=cnt+1;++k)
a[j][k]-=mul*a[i][k];
}
}
for(i=cnt;i>=0;--i){
for(j=i+1;j<=cnt;++j)
a[i][cnt+1]-=a[i][j]*b[j];
b[i]=a[i][cnt+1]/a[i][i];
}
}
int main(){
//freopen("rio.txt","r",stdin);
scanf("%d%d%d",&n,&l,&m);
int i,j,x,y;
for(i=0;i<m;++i){
scanf("%d%d",&x,&y);
pro[i]=y==0?0:(double)x/y;
}
for(i=1;i<=n;++i){
scanf("%s",s+1);
insert(i);
}
Build();
for(i=0;i<=cnt;++i)
if(!id[i])
for(j=0;j<m;++j)
a[trans[i][j]][i]+=pro[j];
for(i=0;i<=cnt;++i)
a[i][i]-=1;
a[0][cnt+1]=-1;
Gauss();
for(i=1;i<=n;++i)
printf("%.2f\n",std::fabs(b[pos[i]]));
return 0;
}

BZOJ 3143 - [Hnoi2013]游走
https://blog.sengxian.com/solutions/bzoj-3143

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 510
using namespace std;
typedef double D;
struct T
{
int to,next,w;
}c[MAXN*MAXN];
int n,m;
D a[MAXN][MAXN],f[MAXN],g[MAXN*MAXN],d=1.00;
inline void add(int x,int y,int z)
{
c[++tot].to=y;
c[tot].w=z;
c[++tot].to=x;
c[tot].w=z;
}
int in[MAXN];
inline D abs(D x)
{
return x<0?0-x:x;
}
inline void swap(D &x,D &y)
{
D temp=x;
x=y;
y=temp;
}
inline void gas()
{
for(int i=1,k=1;i<=n;i++,k++)
{
D h=abs(a[i][k]);
int t=i;
for(int j=i+1;j<=n;j++)
if(abs(a[j][k]>h))
{
h=abs(a[j][k]);
t=j;
}
if(t!=i)
{
for(int j=k;j<=n+1;j++)
swap(a[i][j],a[t][j]);
}
for(int j=i+1;j<=n;j++)
{
D to=a[j][k]/a[i][k];
for(int l=k;l<=n+1;l++)
a[j][l]-=a[i][l]*to;
}
}
for(int i=n;i>0;i--)
{
for(int j=i+1;j<=n;j++)
a[i][n+1]-=a[i][j]*f[j];
f[i]=a[i][n+1]/a[i][i];
}
}
inline void work()
{
for(int i=1;i<n;i++)
g[c[j].w]+=f[i]/in[i];
sort(g+1,g+m+1);
D ans=0;
for(int i=1;i<=m;i++)
ans+=(D)(m-i+1)*g[i];
printf("%.3lf",ans);
}
int main()
{

scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
in[x]++;
in[y]++;
}
in[n]=1;
for(int i=1;i<=n;i++)
{
a[i][i]=-1;
if(c[j].to!=n)
a[i][c[j].to]=(D)(d/in[c[j].to]);
a[i][n+1]=0.00;
}
a[1][n+1]=-1.00;
gas();
work();
return 0;
}
Kod

BZOJ 3640 - JC的小苹果
https://blog.sengxian.com/solutions/bzoj-3640

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
const int N=155;
const int M=5010;
const int H=10010;
int n,m,hp,co[N];
double a[N][N],b[N],f[H][N];
struct B{
double x[N];
inline friend B operator -(B w,B q){
int i;
for(i=1;i<=n;++i)
w.x[i]-=q.x[i];
return w;
}
inline friend B operator *(B w,double q){
int i;
for(i=1;i<=n;++i)
w.x[i]*=q;
return w;
}
inline double get(){
double ret=0;
int i;
for(i=1;i<=n;++i)
ret+=x[i]*b[i];
return ret;
}
}bi[N];
struct V{
int to,next;
}c[M<<1];
int degree[N];
}
inline void Gauss(){
int i,j,k,idx;
double mul;
for(i=1;i<=n;++i){
idx=i;
for(j=i+1;j<=n;++j)
if(std::fabs(a[j][i])>std::fabs(a[idx][i]))
idx=j;
if(idx!=i){
for(j=i;j<=n;++j)
std::swap(a[i][j],a[idx][j]);
std::swap(bi[i],bi[idx]);
}
for(j=1;j<=n;++j){
if(i==j)continue;
mul=a[j][i]/a[i][i];
for(k=i;k<=n;++k)
a[j][k]-=a[i][k]*mul;
bi[j]=bi[j]-bi[i]*mul;
}
}
}
inline void Gauss(double *e){
int i,j;
double sum;
for(i=n;i>0;--i)
e[i]=bi[i].get()/a[i][i];
}
inline void Init(){
scanf("%d%d%d",&n,&m,&hp);
int i,j,x,y;
for(i=1;i<=n;++i)
scanf("%d",&co[i]);
for(i=1;i<=m;++i){
scanf("%d%d",&x,&y);
if(x==y){
++degree[x];
continue;
}
++degree[x],++degree[y];
}
for(i=1;i<=n;++i){
bi[i].x[i]=1;
if(co[i])a[i][i]=1;
else{
a[i][i]=-1;
if(c[j].to!=n)
a[i][c[j].to]+=1./degree[c[j].to];
}
}
Gauss();
}
inline void Work(){
int i,j,k;
for(i=hp;i>0;--i){
for(j=1;j<=n;++j){
b[j]=0;
if(j==1&&i==hp)
b[j]=-1;
else if(!co[j])
b[j]=0;
else if(i+co[j]<=hp)
if(c[k].to!=n)
b[j]+=f[i+co[j]][c[k].to]/degree[c[k].to];
}
Gauss(f[i]);
}
}
inline void Print(){
double ans=0;
int i;
for(i=1;i<=hp;++i)
ans+=f[i][n];
printf("%.8lf\n",ans);
}
int main(){
//freopen("rio.txt","r",stdin);
Init();
Work();
Print();
return 0;
}
Kod

posted @ 2018-04-10 18:56  TS_Hugh  阅读(208)  评论(0编辑  收藏