diff --git a/src/11/13/P7297.cpp b/src/11/13/P7297.cpp index c7a950f..e7e94ce 100644 --- a/src/11/13/P7297.cpp +++ b/src/11/13/P7297.cpp @@ -7,7 +7,10 @@ #include #include #include -using ll = int; +// 引入这个头文件以使用 abs +#include + +using ll = int; // 距离不会爆int,用int更快一点 const ll maxn=5e4+5,maxk=51,inf=1e9+7; ll n,k,b[maxn]; @@ -21,7 +24,7 @@ struct P{ return step>o.step; } }; -#define printf + int main(){ std::iostream::sync_with_stdio(false); std::cin.tie(nullptr); @@ -34,6 +37,8 @@ int main(){ classp[b[i]].emplace_back(i); vis[i]=inf; } + // 注意:classp 中的下标天然就是有序的(从小到大),所以不需要额外排序 + for(ll i=1;i<=k;i++){ for(ll j=1;j<=k;j++){ char tmp; @@ -43,27 +48,57 @@ int main(){ } } } + std::priority_queue

pq; pq.emplace(1,0); + // vis[1] = 0; // 严谨的Dijkstra最好在这里初始化,不过你的逻辑在下面判断也可以 + while(pq.size()){ auto[now,step]=pq.top(); pq.pop(); - if(vis[now]!=inf)continue; - vis[now]=std::min(step,vis[now]); - printf("dij now=%lld, step=%lld\n",now,step); + + // 这里的逻辑稍微调整一下,符合标准Dijkstra + if(vis[now]!=inf) continue; + vis[now]=step; + if(now==n){ std::cout<vis[p])continue; - pq.emplace(p,step+std::abs(p-now)); + + // --- 修改开始 --- + for(ll target_breed : edg[b[now]]){ + // 获取目标品种的所有位置列表 + const auto& vec = classp[target_breed]; + if(vec.empty()) continue; + + // 1. 找右边最近的一个 (第一个 > now 的位置) + auto it = std::upper_bound(vec.begin(), vec.end(), now); + if(it != vec.end()){ + ll p = *it; + ll nstep = step + std::abs(p - now); + // 只有当新路径更短,且该点未被“关闭”(未vis)时才入队 + // 注意:你之前的逻辑里 vis[p] 初始化是 inf,所以用 nstep < vis[p] 没问题 + // 但要注意 vis 在你的代码里既做“已访问标记”又存“最短路”。 + // 更安全的写法是只判断是否更优,因为如果 vis[p] 已经是更小的值,这里就不会进 + if(vis[p] == inf) { + pq.emplace(p, nstep); + } + } + + // 2. 找左边最近的一个 (第一个 < now 的位置) + // lower_bound 是 >= now,所以它的前一个就是 < now + auto it_l = std::lower_bound(vec.begin(), vec.end(), now); + if(it_l != vec.begin()){ + it_l--; // 往前移一位 + ll p = *it_l; + ll nstep = step + std::abs(p - now); + if(vis[p] == inf) { + pq.emplace(p, nstep); + } } } + // --- 修改结束 --- } std::cout<<"-1\n"; } \ No newline at end of file