洛谷 P6154 游走(toposort+期望)

题目链接:https://www.luogu.com.cn/problem/P6154

拓扑排序+快速幂求逆元

AC代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<queue>
 4 #include<cstring>
 5 using namespace std;
 6 typedef long long ll;
 7 const int N=500005;
 8 const ll mod=998244353;
 9 int n,m,tot;
10 ll ans,res;
11 queue<int> q;
12 int head[N],in[N];
13 ll sum[N],num[N];
14 struct node{
15     int to,next;
16 }edge[N<<1];
17 void add(int u,int v){
18     edge[tot].to=v;
19     edge[tot].next=head[u];
20     head[u]=tot++;
21 }
22 ll quick_pow(ll a,ll b){
23     ll anss=1;
24     while(b){
25         if(b&1) ans=ans*a%mod;
26         a=a*a%mod;
27         b>>=1;
28     }
29     return anss;
30 }
31 void toposort(){
32     for(int i=1;i<=n;i++) if(!in[i]) q.push(i);
33     while(!q.empty()){
34         int u=q.front(); q.pop();
35         for(int i=head[u];i!=-1;i=edge[i].next){
36             int v=edge[i].to;
37             in[v]--;
38             num[v]=(num[v]+num[u])%mod;
39             sum[v]=(sum[v]+sum[u]+num[u])%mod;
40             if(!in[v]) q.push(v);
41         }
42     }
43     for(int i=1;i<=n;i++){
44         res=(res+num[i])%mod;
45         ans=(ans+sum[i])%mod;
46     }
47 }
48 int main(){
49     scanf("%d%d",&n,&m);
50     memset(head,-1,sizeof(head));
51     memset(num,1,sizeof(num));
52     for(int i=1;i<=m;i++){
53         int x,y;
54         scanf("%d%d",&x,&y);
55         add(x,y);
56         in[y]++;
57     }
58     toposort();
59     printf("%lld
",(quick_pow(res,mod-2)*ans)%mod);
60     return 0;
61 }
AC代码
原文地址:https://www.cnblogs.com/New-ljx/p/13933740.html