【Luogu】P3232游走(高斯消元解概率)
参见远航之曲dalao的题解,我再写一遍的话就没啥意思了。
#include<cstdio> #include<cstring> #include<algorithm> #include<cctype> #include<cstdlib> #include<cmath> #define maxn 505 using namespace std; inline long long read(){ long long num=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-'0'; ch=getchar(); } return num*f; } double s[maxn][maxn]; double indl[maxn]; struct Edge{ int next,to; }edge[maxn*maxn]; int head[maxn],num; inline void add(int from,int to){ edge[++num]=(Edge){head[from],to}; head[from]=num; } struct Node{ int from,to;double p; bool operator <(const Node &a)const{ return p<a.p; } }q[maxn*maxn]; double ans[maxn]; int main(){ int n=read(),m=read(); for(int i=1;i<=m;++i){ int x=read(),y=read(); indl[x]++; indl[y]++; add(x,y); add(y,x); q[i]=(Node){x,y,0}; } for(int i=1;i<n;++i){ s[i][i]=1; for(int j=head[i];j;j=edge[j].next){ int to=edge[j].to; if(to!=n) s[i][to]=-1/indl[to]; } } s[1][n]=1; for(int i=1;i<n;++i){ int now=i; for(int j=i+1;j<n;++j) if(fabs(s[now][i])<fabs(s[j][i])) now=j; if(now^i) swap(s[now],s[i]); double ret=s[i][i]; for(int j=i;j<=n;++j) s[i][j]/=ret; for(int j=i+1;j<n;++j){ ret=s[j][i]; for(int k=1;k<=n;++k) s[j][k]-=ret*s[i][k]; } } ans[n-1]=s[n-1][n]; for(int i=n-2;i;--i){ ans[i]=s[i][n]; for(int j=i+1;j<n;++j) ans[i]-=ans[j]*s[i][j]; } for(int i=1;i<=m;++i) q[i].p=ans[q[i].from]/indl[q[i].from]+ans[q[i].to]/indl[q[i].to]; sort(q+1,q+m+1); double fin=0; for(int i=1;i<=m;++i) fin+=q[i].p*(m-i+1); printf("%.3lf",fin); return 0; }