【题解】Luogu P3953 逛公园 最短路+记忆化搜索

先%王第一$OTZ$,$tql$

然后...题解我咕了,移步王第一

code

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 namespace gengyf{
 4 #define ll long long
 5 const int maxn=1e6+10;
 6 inline int read(){
 7     int x=0,f=1;
 8     char c=getchar();
 9     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
10     while(c>='0'&&c<='9'){x=(x*10)+c-'0';c=getchar();}
11     return x*f;
12 }
13 struct edge{
14     int to,w;
15 };
16 vector<edge>head[maxn],h[maxn];
17 int n,m,k,p,T;
18 int d[maxn],f[maxn][55];
19 bool v[maxn][55];
20 void spfa(){
21     memset(d,0x3f,sizeof(d));
22     memset(f,-1,sizeof(f));
23     queue<int>q;
24     q.push(1);d[1]=0;
25     while(!q.empty()){
26         int x=q.front();q.pop();
27         for(int i=0;i<head[x].size();i++){
28             int y=head[x][i].to;
29             int z=head[x][i].w;
30             if(d[y]>d[x]+z){
31                 d[y]=d[x]+z;q.push(y);
32             }
33         }
34     }
35 }
36 int dfs(int x,int y){
37     int tmp=0;
38     if(y<0||y>k)return 0;
39     if(v[x][y]){
40         v[x][y]=0;return -1;
41     }
42     if(f[x][y]!=-1)return f[x][y];
43     v[x][y]=1;
44     for(int i=0;i<h[x].size();i++){
45         int to=h[x][i].to;
46         int w=h[x][i].w;
47         int val=dfs(to,d[x]+y-d[to]-w);
48         if(val==-1){
49             v[x][y]=0;return -1;
50         }
51         tmp=(tmp+val)%p;
52     }
53     v[x][y]=0;
54     if(x==1&&y==0)tmp++;
55     f[x][y]=tmp;
56     return tmp;
57 }
58 int main(){
59     T=read();
60     while(T--){
61         n=read();m=read();k=read();p=read();
62         for(int i=1;i<=n;i++){
63             h[i].clear();head[i].clear();
64         }
65         for(int i=1;i<=m;i++){
66             int x,y,z;x=read();y=read();z=read();
67             head[x].push_back(edge{y,z});
68             h[y].push_back(edge{x,z});
69         }
70         spfa();
71         int ans=0;
72         
73         for(int i=0;i<=k;i++){
74             int val=dfs(n,i);
75             if(val==-1){
76                 puts("-1");goto here;
77             }
78             ans=(ans+val)%p;
79         }
80         printf("%d\n",ans);
81         here:;
82     }
83     return 0;
84 }
85 }
86 signed main(){
87   gengyf::main();
88   return 0;
89 }
View Code

 

posted @ 2019-10-08 09:44  喵の耳  阅读(138)  评论(0编辑  收藏  举报