Loading

P3232

P3232
显然将边被走过期望求出来,然后sort一下完事。
经典套路,边过多,考虑点上做文章。
显然的文章就是期望,那么\(f(i)\)表示经过点i的期望数,怎么球?
记\(X_t\)表示第t秒走到的点,那么

\[f(i)=E[\sum_{t=0}^{\infty}I_t(i)]=\sum_{t=0}^{\infty}P(x_t=i) \]

用全概率公式就是

\[\begin{align} f(i)&=\sum_{t=0}^{\infty} \sum_j \frac{1}{dep_{j}}P(X_{t-1}=j)P(X_t=i)\\ &=\sum_{j}\frac{1}{dep_j}P(X_{t-1}=j)\\ &=\sum_{j}\frac{1}{dep_j}f(j)\\ \end{align} \]

那么显然用高斯消元即可解决。

\[\begin{cases} f(i)=\sum_{(i,j) \in E,j!=N}f_j,1<i< n f(i)=\sum_{(i,j) \in E,j!=N}f_j+1,i=1 \end{cases} \]

code
#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define ld long double
void rd(ll& x)
{
    char ch=getchar();
    ll f=1;x=0;
    while(ch<'0'||ch>'9'){
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-48;
        ch=getchar();
    }
    x=x*f;
}
const ll N_ = 505,esp=1e-8;
ld ans,f[N_],a[N_][N_],b[N_];
ll N,M,d[N_];
vector<ll> q[N_];
struct Node{
    ll u,v;ld val;
}edge[125010];
int main()
{
    // freopen("P3232_4.in","r",stdin);
    rd(N);rd(M);
    for(int i=1;i<=M;i++){
        ll u,v;
        rd(u);rd(v);
        edge[i]={u,v,0};
        q[u].push_back(v);
        q[v].push_back(u);
        d[u]++;d[v]++;
    }
    for(int i=1;i<N;i++)
    {
        for(auto j:q[i]){
            if(j==N)continue;
            a[i][j]=1.0/d[j];
        }
        a[i][i]=-1;
        if(i==1)b[i]=-1;
    }
    ll row=1;
    // return 0;
    for(int j=1;j<N;j++){
        ll m=row;
        for(int i=row;i<N;i++)
            if(a[m][j]<a[i][j])m=i;
        if(std::abs(a[m][j])<esp)continue;
        for(int i=1;i<N;i++)swap(a[m][i],a[row][i]);
        swap(b[m],b[row]);
        for(int i=1;i<N;i++){
            if(i==row)continue;
            ld rate=a[i][j]*1.0/a[row][j];
            for(int h=1;h<N;h++)a[i][h]-=rate*a[row][h];
            b[i]-=rate*b[row];
        }
        row++;
    }
    // return 0;
    for(int i=1;i<N;i++){
        if(!a[i][i])cout<<0,exit(0);
        f[i]=b[i]*1.0/a[i][i];
    }
    for(int i=1;i<=M;i++){
        ll u=edge[i].u,v=edge[i].v;
        edge[i].val=f[u]*1.0/d[u]+f[v]*1.0/d[v];
    }
    sort(edge+1,edge+1+M,[](Node x,Node y){
        return x.val>y.val;
    });
    for(int i=1;i<=M;i++)ans=ans+(edge[i].val*i);
    printf("%.3Lf",ans);
    return 0;
}

小结:边过多,考虑点上做文章

posted @ 2026-09-08 11:06  leaf_ydc  阅读(5)  评论(0)    收藏  举报