P6154 游走(数学期望)

题意:

在这里插入图片描述
数据范围:n<=1e5,m<=7e5

解法:

题目要求路径长度的期望.

选到每一条路径的概率相同.
设路径总数量为cnt,那么每条路径对期望的贡献为len/cnt.
因为对于固定的图,cnt是定值,
所以求出所有路径的长度和即可计算答案

令cnt[x]为以点x为结尾的路径数量,
令len[x]为以点x为结尾的路径总长度,
DAG上dp一下就行了,用拓扑排序进行转移.

code:

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxm=1e5+5;
const int mod=998244353;
vector<int>g[maxm];
int cnt[maxm];
int len[maxm];
int in[maxm];
int n,m;
int ppow(int a,int b,int mod){
    
    
    int ans=1%mod;a%=mod;
    for(;b;b>>=1,a=a*a%mod)if(b&1)ans=ans*a%mod;
    return ans;
}
signed main(){
    
    
    ios::sync_with_stdio(0);
    cin>>n>>m;
    for(int i=1;i<=m;i++){
    
    
        int a,b;cin>>a>>b;
        g[a].push_back(b);
        in[b]++;
    }
    queue<int>q;
    for(int i=1;i<=n;i++){
    
    //每个点有一个自己到自己的路径
        cnt[i]=1;
    }
    for(int i=1;i<=n;i++){
    
    
        if(!in[i]){
    
    
            q.push(i);
        }
    }
    while(q.size()){
    
    
        int x=q.front();q.pop();
        for(int v:g[x]){
    
    
            if(in[v]){
    
    
                in[v]--;
                cnt[v]+=cnt[x];
                cnt[v]%=mod;
                len[v]+=len[x]+cnt[x];
                len[v]%=mod;
                if(!in[v]){
    
    
                    q.push(v);
                }
            }
        }
    }
    int up=0,down=0;
    for(int i=1;i<=n;i++){
    
    
        up+=len[i];
        up%=mod;
        down+=cnt[i];
        down%=mod;
    }
    cout<<up*ppow(down,mod-2,mod)%mod<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44178736/article/details/112750259