旅行的意义 Gym - 102174L

题目链接:

旅行的意义

 Gym - 102174L 

题目大意:

天天身在 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)。因此答案请以 PQ1 (mod 998244353)P⋅Q−1 (mod 998244353) 的形式输出,其中 Q1Q−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\n",ans);
61     }
62     return 0;
63 }

 

posted @ 2019-05-04 10:13  Let_Life_Stop  阅读(408)  评论(0编辑  收藏  举报