P6154 游走

其中一条道路的期望贡献为

\(\huge{\frac{dis}{s}}\)

全部的期望为
\(\huge{\frac{\sum dis}{s}}\)

其中s为路径条数

建反图拓扑排序就能求出。

#include<bits/stdc++.h>
#include<queue>
#define int long long
using namespace std;
#define orz cout<<"lyakioi!!!!!!!!!!!!!!!!!"<<endl
inline int r(){int s=0,k=1;char c=getchar();while(!isdigit(c)){if(c=='-')k=-1;c=getchar();}while(isdigit(c)){s=s*10+c-'0';c=getchar();}return s*k;}
const int mod=998244353;
int n,m,head[1000001],cnt;
struct node
{
	int to,next;
}a[1000001];
void add_edge(int from,int to)
{
	a[++cnt].to=to;
	a[cnt].next=head[from];
	head[from]=cnt;
}
int rd[1000001],f[1000001],g[1000001],ans1,ans2;
queue<int>q;
int pw(int a,int b)
{
	int ans=1;
	while(b)
	{
		if(b&1)ans*=a;
		ans%=mod;
		a*=a;
		a%=mod;
		b>>=1;
	}
	return ans;
}
signed main()
{
	int x,y;
	n=r();m=r();
	for(int i=1;i<=m;i++)
	{
		y=r();x=r();
		add_edge(x,y);
		rd[y]++;
	}
	for(int i=1;i<=n;i++)
	{
		if(!rd[i])q.push(i);
		f[i]=1;
	}
	
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		ans1+=g[u];ans2+=f[u];
		ans1%=mod;ans2%=mod;
		for(int i=head[u];i;i=a[i].next)
		{
			int v=a[i].to;
			f[v]+=f[u];
			f[v]%=mod;
			g[v]+=g[u]+f[u];
			g[v]%=mod;
			rd[v]--;if(!rd[v])q.push(v);
		}
	}
	
//	cout<<ans1<<" "<<ans2<<endl;
	cout<<ans1*pw(ans2,mod-2)%mod;
}
posted @ 2021-09-03 18:35  lei_yu  阅读(18)  评论(0编辑  收藏  举报