题目链接
题意分析
说实在的 被绿题卡了跟被驴踢了的感觉差不多
不过是概率问题 还是情有可原的捂脸
这道题 说白了 我们假设len是所有路径的长度和 sum是所有路径的数量
那么答案就是(frac{len}{sum})
首先的话 这是一道有向无环图的题 所以我们可以考虑来个拓扑排序
记录两个状态a[i]还有b[i]
a[i]表示所有到i位置的路径长度和
b[i]表示所有到i位置的路径数量(包括起点与终点相同 所以初始化为1)
那么状态转移就是
(a[i]=sum{a[j]+b[j],j→i}) 从j转移到i 所有的路径长度都会+1
(b[i]=sum{b[j],j→i})
CODE:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#define mod 998244353
#define N 1008611
using namespace std;
int n,m,tot;
int to[N],nex[N],head[N];
int in[N];
long long ans1,ans2;
long long cdy[N],wzy[N];
queue<int> que;
long long qpow(long long x,int y)
{long long res=1;for(;y;y>>=1,x=x*x%mod) if(y&1) res=res*x%mod;return res;}
void add(int x,int y)
{to[++tot]=y;nex[tot]=head[x];head[x]=tot;}
void DPsort()
{
for(int i=1;i<=n;++i) wzy[i]=1LL;
for(int i=1;i<=n;++i)
if(!in[i]) que.push(i);
while(!que.empty())
{
int u=que.front();que.pop();
for(int i=head[u];i;i=nex[i])
{
int v=to[i];
wzy[v]=(wzy[v]+wzy[u])%mod;
cdy[v]=(cdy[v]+wzy[u]+cdy[u])%mod;
in[v]--;
if(!in[v]) que.push(v);
}
}
// for(int i=1;i<=n;++i)
// printf("%d %d
",cdy[i],wzy[i]);
for(int i=1;i<=n;++i)
ans1=(ans1+cdy[i])%mod,ans2=(ans2+wzy[i])%mod;
printf("%lld
",ans1*qpow(ans2,mod-2)%mod);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1,x,y;i<=m;++i)
{
scanf("%d%d",&x,&y);
add(x,y);in[y]++;
}
DPsort();
return 0;
}