P6154 遊走 簡單期望
阿新 • • 發佈:2021-07-08
2 P6154 遊走 簡單期望
不難發現,所有的路徑被選概率都是一樣的,也就是說,所有的路徑被選的概率是 \(1\) 除以路徑的總條數。再者我們需要算出所有路徑的長度總和。
考慮 dp 。令 \(f_k\) 表示結尾為 \(k\) 的路徑長度總和,\(g_k\) 表示結尾為 \(k\) 的路徑條數。
不難設計一個 dp :
\[f_u\sum\limits_{v,(v,u)\in E} f_v+g_v\\ g_u=\sum\limits_{v,(v,u)\in E}g_v \]累加所有答案算逆元就可以了。
程式碼:
#include<bits/stdc++.h> #define dd double #define ld long double #define ll long long #define int long long #define uint unsigned int #define ull unsigned long long #define N 100010 #define M 700010 using namespace std; const int INF=0x3f3f3f3f; const ll mod=998244353; template<typename T> inline void read(T &x) { x=0; int f=1; char c=getchar(); for(;!isdigit(c);c=getchar()) if(c == '-') f=-f; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; x*=f; } int rd[N],n,m; struct edge{ int to,next; inline void intt(int to_,int ne_){ to=to_;next=ne_; } }; edge li[M]; int head[N],tail; inline void add(int from,int to){ li[++tail].intt(to,head[from]); head[from]=tail; } queue<int> q; ll ans1,ans2,f[N],g[N]; bool vis[N]; inline void solve(){ while(q.size()){ int top=q.front();q.pop();g[top]++;ans1+=f[top];ans2+=g[top]; ans1%=mod;ans2%=mod; for(int x=head[top];x;x=li[x].next){ int to=li[x].to; f[to]+=f[top]+g[top];g[to]+=g[top]; f[to]%=mod;g[to]%=mod; rd[to]--; if(!rd[to]) q.push(to); } } } inline ll ksm(ll a,ll b,ll mod){ a%=mod; ll res=1; while(b){ if(b&1) (res*=a)%=mod; a=a*a%mod; b>>=1; } return res; } signed main(){ read(n);read(m); for(int i=1;i<=m;i++){ int from,to;read(from);read(to); add(from,to);rd[to]++; } for(int i=1;i<=n;i++){ if(!rd[i]) q.push(i); } solve(); // printf("%lld %lld\n",ans1,ans2); ll inv=ksm(ans2,mod-2,mod); printf("%lld\n",ans1*inv%mod); return 0; }