mirror of
https://gitcode.com/Zengtudor/alg2025.git
synced 2025-11-06 06:43:49 +00:00
feat(P3953): 实现基于DFS的路径计数算法替代BFS
用DFS加记忆化搜索替换原有的BFS实现,解决大规模数据下的性能问题 新增距离数组d和动态规划数组dp来优化计算 添加反向图re支持逆向搜索 处理路径计数中的环检测和边界条件
This commit is contained in:
parent
a788926d44
commit
5cb2778d2c
@ -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<std::vector<E>> edg;
|
||||
std::bitset<maxm> vis;
|
||||
std::vector<std::vector<E>> edg,re;
|
||||
std::deque<P>dq;
|
||||
|
||||
sl ll dj(){
|
||||
vis.reset();
|
||||
for(ll i=1;i<=n;i++){
|
||||
d[i]=inf;
|
||||
}
|
||||
std::priority_queue<P> 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<<ans%p<<"\n";
|
||||
std::cout<<ans<<"\n";
|
||||
}
|
||||
|
||||
int main(){
|
||||
|
||||
Loading…
Reference in New Issue
Block a user