[Luogu] 逛公园
https://www.luogu.org/problemnew/show/P3953
https://www.zybuluo.com/wsndy-xx/note/1134388
#include<cstdio> #include<cstring> #include<cctype> using namespace std; const int N=1e5+1,K=51; int n,m,k,p,tot,ans=0; int first[N],next[N<<1],en[N<<1],w[N<<1]; int first1[N*K],next1[N*K<<1],en1[N*K<<1],d[N*K]; int q[N<<6],dis[N],dis1[N],u[N<<1],v[N<<1],t[N<<1],f[N*K]; bool bz[N]; inline int read() { int X=0,w=1; char ch=0; while(!isdigit(ch)) { if(ch=='-') w=-1; ch=getchar(); } while(isdigit(ch)) X=(X<<3)+(X<<1)+ch-'0',ch=getchar(); return X*w; } inline void insert(int x,int y,int z) { next[++tot]=first[x]; first[x]=tot; en[tot]=y; w[tot]=z; } inline void insert1(int x,int y) { next1[++tot]=first1[x]; first1[x]=tot; en1[tot]=y; d[y]++; } inline int get(int x,int y) { return (x-1)*(k+1)+y+1; } int main() { int T=read(); while(T--) { n=read(),m=read(),k=read(),p=read(); memset(first,tot=0,sizeof(first)); for(int i=1; i<=m; i++) { u[i]=read(),v[i]=read(),t[i]=read(); insert(u[i],v[i],t[i]); } memset(dis,60,sizeof(dis)); int l=dis[1]=0,r=q[1]=1; while(l<r) { int x=q[++l]; bz[x]=false; for(int i=first[x]; i; i=next[i]) if(dis[x]+w[i]<dis[en[i]]) { dis[en[i]]=dis[x]+w[i]; if(!bz[en[i]]) bz[q[++r]=en[i]]=true; } } memset(first,tot=0,sizeof(first)); for(int i=1; i<=m; i++) insert(v[i],u[i],t[i]); memset(dis1,60,sizeof(dis1)); l=dis1[q[r=1]=n]=0; while(l<r) { int x=q[++l]; bz[x]=false; for(int i=first[x]; i; i=next[i]) if(dis1[x]+w[i]<dis1[en[i]]) { dis1[en[i]]=dis1[x]+w[i]; if(!bz[en[i]]) bz[q[++r]=en[i]]=true; } } memset(first1,tot=0,sizeof(first1)); memset(d,0,sizeof(d)); for(int i=1; i<=m; i++) { int x=get(u[i],0),y=get(v[i],dis[u[i]]+t[i]-dis[v[i]]); for(int j=dis[u[i]]; j+t[i]+dis1[v[i]]<=dis[n]+k; j++,x++,y++) insert1(x,y); } int num=(k+1)*n,sum=0; l=r=ans=0; memset(f,0,sizeof(f)); for(int i=1; i<=num; i++) if(!d[i]) q[++r]=i; f[1]=1; while(l<r) { int x=q[++l]; sum++; for(int i=first1[x]; i; i=next1[i]) { if(!--d[en1[i]]) q[++r]=en1[i]; f[en1[i]]+=f[x]; f[en1[i]]=f[en1[i]]>p?f[en1[i]]-p:f[en1[i]]; } } if(sum<num) printf("-1\n"); else { for(int i=0; i<=k; i++) ans=(ans+f[get(n,i)])%p; printf("%d\n",ans); } } return 0; }