From 5cb2778d2c04c3801dbad8f72e7b10fc78a9996a Mon Sep 17 00:00:00 2001 From: Zengtudor Date: Wed, 5 Nov 2025 16:17:11 +0800 Subject: [PATCH] =?UTF-8?q?feat(P3953):=20=E5=AE=9E=E7=8E=B0=E5=9F=BA?= =?UTF-8?q?=E4=BA=8EDFS=E7=9A=84=E8=B7=AF=E5=BE=84=E8=AE=A1=E6=95=B0?= =?UTF-8?q?=E7=AE=97=E6=B3=95=E6=9B=BF=E4=BB=A3BFS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用DFS加记忆化搜索替换原有的BFS实现,解决大规模数据下的性能问题 新增距离数组d和动态规划数组dp来优化计算 添加反向图re支持逆向搜索 处理路径计数中的环检测和边界条件 --- src/11/5/P3953.cpp | 84 +++++++++++++++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 27 deletions(-) diff --git a/src/11/5/P3953.cpp b/src/11/5/P3953.cpp index cb669d2..2f2d900 100644 --- a/src/11/5/P3953.cpp +++ b/src/11/5/P3953.cpp @@ -8,8 +8,9 @@ using ll = int64_t; #define sl static inline // #define printf -const ll maxm=2e5+5; -ll n,m,k,p,nt; +const ll maxm=2e5+5,inf=1e9+7; +ll n,m,k,p,nt,d[maxm],dp[maxm][57]; +bool isn,vis[maxm][57]; struct E{ ll v,w; }; @@ -19,36 +20,78 @@ struct P{ return step>o.step; } }; -std::vector> edg; -std::bitset vis; +std::vector> edg,re; std::deque

dq; sl ll dj(){ - vis.reset(); + for(ll i=1;i<=n;i++){ + d[i]=inf; + } std::priority_queue

pq; pq.emplace(1,0); while(pq.size()){ auto[now,step]=pq.top(); + // printf("dj now=%lld, step=%lld\n",now,step); pq.pop(); - if(now==n)return step; - if(vis[now])continue; - vis[now]=true; + if(step>=d[now])continue; + d[now]=step; for(auto[v,w]:edg[now]){ pq.emplace(v,step+w); } } - return -1; + + printf("d[]:"); + for(ll i=1;i<=n;i++){ + printf("%lld ",d[i]); + } + printf("\n"); + return d[n]==inf?-1:d[n]; +} + +sl ll dfs(ll u,ll k){ + if(k<0||k>::k)return 0; + if(vis[u][k]){ + isn=true; + return 0; + } + if(u==1)return k==0?1:0; + vis[u][k]=true; + if(dp[u][k]!=-1){ + return dp[u][k]; + } + ll nans=0; + for(auto[v,w]:re[u]){ + ll nk=d[u]+k-d[v]-w; + if(nk<0||nk>k)continue; + nans=(nans+dfs(v, nk))%p; + if(isn){ + return 0; + } + } + vis[u][k]=false; + return dp[u][k]=nans; } sl void solve(){ printf("NT = %lld\n",++nt); std::cin>>n>>m>>k>>p; + isn=false; edg.clear(); edg.resize(n+1); + re.clear(); + re.resize(n+1); + for(ll i=1;i<=n;i++){ + for(ll j=1;j<=50;j++){ + dp[i][j]=-1; + vis[i][j]=false; + } + } + dp[1][0]=1; for(ll i=1;i<=m;i++){ ll u,v,w; std::cin>>u>>v>>w; edg[u].emplace_back(v,w); + re[v].emplace_back(u,w); } const ll d = dj(); printf("found d=%lld\n",d); @@ -58,27 +101,14 @@ sl void solve(){ } const ll ms=d+k; ll ans=0; - dq.clear(); - dq.emplace_back(1,0); - ll tick=0; - while(dq.size()){ - tick++; - if(tick>1e6){ - std::cout<<-1<<"\n"; + for(ll i=0;i<=k;i++){ + ans=(ans+dfs(n,i))%p; + if(isn){ + std::cout<<"-1\n"; return; } - auto[now,step]=dq.front(); - dq.pop_front(); - if(now==n){ - ans++; - } - for(auto[v,w]:edg[now]){ - const ll ns=w+step; - if(ns>ms)continue; - dq.emplace_back(v,ns); - } } - std::cout<