BZOJ3143 游走 [期望][高斯消元]

来源:互联网 发布:法国德国人 知乎 编辑:程序博客网 时间:2024/05/09 00:15

本人蒟蒻,反正本只会用高斯消元做这道题,求出每个情况的系数,上期望算法乱搞就行了。
注意高斯消元的for循环,起止点很乱,最好手动推一推。

#include<bits/stdc++.h>using namespace std;const int N=505,M=250500;const int eps=1e-9;int mp[N][N],d[N],a[M],b[M],m,n;double C[N][N],val[M],num[N],ans;template<class T>inline void read(T &res){    static char ch;T flag=1;    while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;res=ch-48;    while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;res*=flag;}double ABS(double x){return x<0?-x:x;}void swap(double &x,double &y){double t=x;x=y;y=t;}void Gauss(){    for(register int i=1;i<=n-1;i++){        int tmp=i;        for(register int j=i+1;j<=n;++j)if(ABS(C[j][i])>ABS(C[tmp][i])+eps)tmp=j;        if(tmp-i)for(register int j=i;j<=n+1;j++)swap(C[i][j],C[tmp][j]);        for(register int j=i+1;j<=n;j++)            for(register int l=n+1;l>=i;l--)                C[j][l]=C[i][l]*C[j][i]/C[i][i]-C[j][l];    }    for(register int i=n;i>=1;i--){        num[i]=C[i][n+1];        for(register int j=i+1;j<=n;j++)num[i]-=num[j]*C[i][j];        (C[i][i])?num[i]/=C[i][i]:num[i]=0;    }}int main(){    read(n),read(m);    for(register int i=1;i<=m;i++){        read(a[i]),read(b[i]);        mp[a[i]][b[i]]++,mp[b[i]][a[i]]++,d[a[i]]++,d[b[i]]++;    }    for(register int i=1;i<=n-2;++i)        for(register int j=1;j<=n-1;++j)            C[i][j]=(i-j)?(1.0*mp[i][j])/d[j]:-1;    for(register int i=1;i<=n-2;++i)C[i][n]=(i-1)?0:-1;    C[n-1][n]=1;    for(register int i=1;i<=n-1;i++)C[n-1][i]=1.0*mp[n][i]/d[i];    num[n--]=0;    Gauss();    for(register int i=1;i<=m;i++)      val[i]=num[a[i]]/(1.0*d[a[i]])+num[b[i]]/(1.0*d[b[i]]);    sort(val+1,val+1+m);    for(register int i=1;i<=m;i++)ans+=val[i]*(m-i+1);    printf("%.3lf\n",ans+eps);    return 0;}

这里写图片描述

阅读全文
0 0