Code:
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<string> using namespace std; const int maxn=400000+4; int d[maxn],s, n ,m, mod,tot; struct SPFA{ int head[maxn],to[maxn],nex[maxn],val[maxn],cnt; void addedge(int u,int v,int c){ nex[++cnt]=head[u],head[u]=cnt,to[cnt]=v,val[cnt]=c; } queue<int>Q; bool inq[maxn]; void init(){ memset(head,0,sizeof(head)), memset(to,0,sizeof(to)), memset(nex,0,sizeof(nex)), memset(val,0,sizeof(val)); cnt=0; } void spfa(){ memset(d,0x3f,sizeof(d)); memset(inq,false,sizeof(inq)); d[s]=0,inq[s]=true; Q.push(s); while(!Q.empty()){ int u=Q.front();Q.pop(); inq[u]=false; for(int v=head[u];v;v=nex[v]){ if(d[u]+val[v]<d[to[v]]){ d[to[v]]=d[u]+val[v]; if(!inq[to[v]]){ Q.push(to[v]); inq[to[v]]=true; } } } } } }T; int head[maxn], to[maxn], nex[maxn], val[maxn], cnt; void addedge(int u,int v,int c){ nex[++cnt]=head[u], head[u]=cnt, to[cnt]=v, val[cnt]=c; } int dp[100007][60]; bool vis[100007][60]; int dfs(int u,int k){ if(vis[u][k]) return -1; if(dp[u][k]!=-1) return dp[u][k]; vis[u][k]=1; int sum=0; for(int v=head[u];v;v=nex[v]){ int tmp=k-(d[to[v]]+val[v]-d[u]); if(tmp<0||tmp>tot) continue; int delta=dfs(to[v], tmp); if(delta==-1) return -1; sum=(sum+delta)%mod; } if(k==0&&u==n) sum+=1; vis[u][k]=0; dp[u][k]=sum; return sum; } int work(){ memset(dp,-1,sizeof(dp)); memset(head,0,sizeof(head)); memset(to,0,sizeof(to)); memset(val,0,sizeof(val)); cnt=0; T.init(); scanf("%d%d%d%d",&n,&m,&tot,&mod); for(int i=1;i<=m;++i){ int a,b,c; scanf("%d%d%d",&a,&b,&c); T.addedge(b,a,c); // 返向 addedge(a,b,c); // 正向 } s=n; T.spfa(); int ans=0; for(int i=0;i<=tot;++i){ memset(vis,0,sizeof(vis)); int aa=dfs(1,i); if(aa==-1) return -1; ans=(ans+aa)%mod; } return ans; } int main(){ int T; scanf("%d",&T); while(T--) printf("%d\n",work()); return 0; }
原文:https://www.cnblogs.com/guangheli/p/9896250.html