mirror of
https://gitcode.com/Zengtudor/alg2025.git
synced 2025-11-06 14:53:47 +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;
|
using ll = int64_t;
|
||||||
#define sl static inline
|
#define sl static inline
|
||||||
// #define printf
|
// #define printf
|
||||||
const ll maxm=2e5+5;
|
const ll maxm=2e5+5,inf=1e9+7;
|
||||||
ll n,m,k,p,nt;
|
ll n,m,k,p,nt,d[maxm],dp[maxm][57];
|
||||||
|
bool isn,vis[maxm][57];
|
||||||
struct E{
|
struct E{
|
||||||
ll v,w;
|
ll v,w;
|
||||||
};
|
};
|
||||||
@ -19,36 +20,78 @@ struct P{
|
|||||||
return step>o.step;
|
return step>o.step;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
std::vector<std::vector<E>> edg;
|
std::vector<std::vector<E>> edg,re;
|
||||||
std::bitset<maxm> vis;
|
|
||||||
std::deque<P>dq;
|
std::deque<P>dq;
|
||||||
|
|
||||||
sl ll dj(){
|
sl ll dj(){
|
||||||
vis.reset();
|
for(ll i=1;i<=n;i++){
|
||||||
|
d[i]=inf;
|
||||||
|
}
|
||||||
std::priority_queue<P> pq;
|
std::priority_queue<P> pq;
|
||||||
pq.emplace(1,0);
|
pq.emplace(1,0);
|
||||||
while(pq.size()){
|
while(pq.size()){
|
||||||
auto[now,step]=pq.top();
|
auto[now,step]=pq.top();
|
||||||
|
// printf("dj now=%lld, step=%lld\n",now,step);
|
||||||
pq.pop();
|
pq.pop();
|
||||||
if(now==n)return step;
|
if(step>=d[now])continue;
|
||||||
if(vis[now])continue;
|
d[now]=step;
|
||||||
vis[now]=true;
|
|
||||||
for(auto[v,w]:edg[now]){
|
for(auto[v,w]:edg[now]){
|
||||||
pq.emplace(v,step+w);
|
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(){
|
sl void solve(){
|
||||||
printf("NT = %lld\n",++nt);
|
printf("NT = %lld\n",++nt);
|
||||||
std::cin>>n>>m>>k>>p;
|
std::cin>>n>>m>>k>>p;
|
||||||
|
isn=false;
|
||||||
edg.clear();
|
edg.clear();
|
||||||
edg.resize(n+1);
|
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++){
|
for(ll i=1;i<=m;i++){
|
||||||
ll u,v,w;
|
ll u,v,w;
|
||||||
std::cin>>u>>v>>w;
|
std::cin>>u>>v>>w;
|
||||||
edg[u].emplace_back(v,w);
|
edg[u].emplace_back(v,w);
|
||||||
|
re[v].emplace_back(u,w);
|
||||||
}
|
}
|
||||||
const ll d = dj();
|
const ll d = dj();
|
||||||
printf("found d=%lld\n",d);
|
printf("found d=%lld\n",d);
|
||||||
@ -58,27 +101,14 @@ sl void solve(){
|
|||||||
}
|
}
|
||||||
const ll ms=d+k;
|
const ll ms=d+k;
|
||||||
ll ans=0;
|
ll ans=0;
|
||||||
dq.clear();
|
for(ll i=0;i<=k;i++){
|
||||||
dq.emplace_back(1,0);
|
ans=(ans+dfs(n,i))%p;
|
||||||
ll tick=0;
|
if(isn){
|
||||||
while(dq.size()){
|
std::cout<<"-1\n";
|
||||||
tick++;
|
|
||||||
if(tick>1e6){
|
|
||||||
std::cout<<-1<<"\n";
|
|
||||||
return;
|
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(){
|
int main(){
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user