3143: [Hnoi2013]游走 概率与期望 高斯消元解期望方程组

第一次做这类题目,我还是太弱了。
首先贪心思想,期望小的赋大权值,期望大的赋小权值,所以关键是求边的期望。设边i的期望为 wi ,点i的期望为 xi ,点i的度数为 di ,则 wi=(u,v) 的期望 wi=xudu+xvdv
那么对于某个点的期望 xi 怎么求呢。
xi=j , exist(i,j)in Exj
然后存在两个特殊的点,即 1 n
由于1号点一定会经过,则
x1=j , exist(1,j)in Exj
由于 n 号点到达后不会出现,所以 n 号点对其他点没有贡献,所以
xn=1
那么就得到了 n1 个方程,高斯消元解一下,最后算出边的期望然后贪心。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define eps 1e-9
using namespace std;
double a[505][505],w[505];
int d[505],head[505],list[500005],next[500005];
int n,m,cnt;
struct node {int x,y;} e[250005];
inline int read()
{
    int a=0,f=1; char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
    return a*f;
}
inline void insert(int x,int y)
{
    d[y]++;
    next[++cnt]=head[x];
    head[x]=cnt;
    list[cnt]=y;
}
inline void gauss()
{
    int y;
    for (int i=1;i<=n;i++)
    {
        for (y=i;y<=n;y++)
            if (fabs(a[y][i])>eps) break;
        if (y>n) continue;
        if (y!=i)
            for (int j=1;j<=n+1;j++) swap(a[y][j],a[i][j]);
        double t=a[i][i];
        for (int j=1;j<=n+1;j++) a[i][j]/=t;
        for (int j=1;j<=n;j++)
            if (j!=i)
            {
                double t=a[j][i];
                for (int k=1;k<=n+1;k++)
                    a[j][k]-=t*a[i][k];
            }
    }
}
int main()
{
// freopen("walk.in","r",stdin);
// freopen("walk.out","w",stdout);

    n=read(); m=read();
    for (int i=1;i<=m;i++)
    {
        e[i].x=read(); e[i].y=read();
        insert(e[i].x,e[i].y);
        if (e[i].x==e[i].y) continue;
        insert(e[i].y,e[i].x);
    }
    for (int i=1;i<=n-1;i++)
    {
        a[i][i]=1;
        for (int j=head[i];j;j=next[j])
        {
            if (list[j]==n) continue;
            a[i][list[j]]-=1.0/d[list[j]];
        }
    }
    a[1][n]=1;
    n--;
    gauss();
    for (int i=1;i<=m;i++)
        w[i]=a[e[i].x][n+1]/(d[e[i].x]*1.0)+a[e[i].y][n+1]/(d[e[i].y]*1.0);
    sort(w+1,w+m+1);
    double ans=0;
    for (int i=1;i<=m;i++) ans+=w[i]*(m-i+1);
    printf("%.3lf\n",ans);
    return 0;
}

你可能感兴趣的:(3143: [Hnoi2013]游走 概率与期望 高斯消元解期望方程组)