题目链接:
旅行的意义
题目大意:
天天身在 11 号城市,他每到达一个旅游城市都会先花一天的时间游玩当地的旅游景点。接下来他也没有明确的目的地,所以第二天他会随机地选择该城市的一条直达线路,花费一天的时间通往下一个旅游城市。当然,如果这个城市的旅游景点太好玩的话,他可能会选择再逗留一天,但是由于假期有限,他在当前的旅游城市最多只能呆 22 天。例如,当天天在城市 CC 时,若城市 CC 有 22 条直达线路分别通往城市 AA 和城市 BB,则在第一天的游玩过后,第二天他有 1313 的可能会选择继续逗留在城市 CC 多游玩一天,但是第三天他一定不会再逗留在城市 CC 了;同时他有 1313 可能会选择立即搭乘直达城市 AA 的高铁;他也有 1313 的可能会选择立即搭乘直达城市 BB的高铁。
当天天把所有的旅游城市都游玩过后,他也就只能结束这段难忘的五一旅行假期了。现在请聪明的你帮天天提前计算一下,他本次旅行时间的期望是多少呢?
容易证明天天旅行时间的期望为 PQPQ 的形式,其中 PP 和 QQ 互质,且 Q≢0 (mod 998244353)Q≢0 (mod 998244353)。因此答案请以 P⋅Q−1 (mod 998244353)P⋅Q−1 (mod 998244353) 的形式输出,其中 Q−1Q−1 表示 QQ 在取模 998244353998244353 下的逆元。
具体思路:
dp[u][0]代表当前天天刚到达u这个城市并且玩了一天。
dp[u][1]代表当前天天打算在u这个城市玩两天。
当二维是0的时候,
dp[u][0]+=(dp[to][0]+1)*(size[u]+1).
// 在城市u已经玩了一天,并且打算用一天的时间乘车去下一个站点
dp[u][0]+=(dp[u][1])*(size[u]+1);
// 在城市u再再玩一天。
dp[u][1]+=(dp[to][0]+1)*(size[u]).
// 在城市u已经玩了两天了,只能选择继续往下一个城市走。
AC代码:
1 #include<bits/stdc++.h>
2 using namespace std;
3 # define ll long long
4 # define inf 0x3f3f3f3f
5 const int mod = 998244353;
6 const int maxn = 2e5+100;
7 int dp[maxn][2];
8 vector<int>Edge[maxn];
9 ll inv[maxn];
10 void init()
11 {
12 inv[1]=1;
13 for(int i=2; i<maxn; i++)
14 {
15 inv[i]=((mod-mod/i)*inv[mod%i]+mod)%mod;
16 }
17 }
18 ll dfs(int u,int type)
19 {
20 if(dp[u][type]!=-1)
21 return dp[u][type];
22 dp[u][type]=1;
23 if(type)
24 {
25 for(auto i:Edge[u])
26 {
27 dp[u][type]=(dp[u][type]+(dfs(i,type^1)+1)*inv[Edge[u].size()]%mod)%mod;
28 }
29 }
30 else
31 {
32 for(auto i:Edge[u])
33 {
34 dp[u][type]=(dp[u][type]+(dfs(i,type)+1)*inv[Edge[u].size()+1]%mod)%mod;
35 }
36 dp[u][type]=(dp[u][type]+(dfs(u,type^1)*inv[Edge[u].size()+1]%mod))%mod;
37 }
38 return dp[u][type]%mod;
39 }
40 int main()
41 {
42 init();
43 int T;
44 scanf("%d",&T);
45 while(T--)
46 {
47 int n,m,st,ed;
48 scanf("%d %d",&n,&m);
49 for(int i=0;i<=n;i++){Edge[i].clear();}
50 for(int i=1; i<=m; i++)
51 {
52 scanf("%d %d",&st,&ed);
53 Edge[st].push_back(ed);
54 }
55 for(int i=1; i<=n; i++)
56 {
57 dp[i][0]=dp[i][1]=-1;
58 }
59 ll ans=dfs(1,0);
60 printf("%lld
",ans);
61 }
62 return 0;
63 }