您的位置:首页 > 其它

BZOJ 3143: [Hnoi2013]游走

2016-04-08 21:52 363 查看
HNOI2013 get!

高斯消元求出每个点经过的次数的期望,然后算出每条边的期望

然后套排序原理,乱序和最小

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define double long double
const int N=500+5;
const double eps=1e-9;
double g

;
void Gauss(int n){
for(int i=1;i<=n;i++){
int j;
for(j=i;j<=n;j++)
if(fabs(g[j][i])>eps)break;
for(int k=i;k<=n;k++)swap(g[i][k],g[j][k]);
for(j=i+1;j<=n;j++){
double t=g[j][i]/g[i][i];
for(int k=i;k<=n+1;k++)
g[j][k]-=t*g[i][k];
}
}
for(int i=n;i>=1;i--){
for(int j=i+1;j<=n;j++)
g[i][n+1]-=g[j][n+1]*g[i][j];
g[i][n+1]/=g[i][i];
}
}
bool e

;
double deg
;
double path[N*N];
int main(){
//freopen("a.in","r",stdin);
int n,m;scanf("%d%d",&n,&m);
while(m--){
int u,v;scanf("%d%d",&u,&v);
e[u][v]=e[v][u]=1;
deg[u]+=1.0;deg[v]+=1.0;
}
for(int i=1;i<=n;i++){
g[i][i]=1.0;
for(int j=1;j<=n;j++)
if(e[j][i])g[i][j]-=1.0/deg[j];
g[i]
=0.0;
}
g

=0.0;g[1]
=1.0;
Gauss(n-1);
double ans=0.0;
int tot=0;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
if(e[i][j])path[++tot]=g[i]
/deg[i]+g[j]
/deg[j];
sort(path+1,path+1+tot);
for(int i=1;i<=tot;i++)
ans+=path[i]*(tot-i+1);
printf("%.3Lf\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: