【题解】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 }