P6154 游走
题目链接
题意分析
说实在的 被绿题卡了跟被驴踢了的感觉差不多
不过是概率问题 还是情有可原的捂脸
这道题 说白了 我们假设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
#include
#include
#include
#include
#include
#include
#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 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\n",cdy[i],wzy[i]);
for(int i=1;i<=n;++i)
ans1=(ans1+cdy[i])%mod,ans2=(ans2+wzy[i])%mod;
printf("%lld\n",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;
}