题意
主角PMP要搭车离开公园,有一个有n个节点m条边的无向图,PMP要从s走到t
因为主角PMP的记性不好,因此他需要志愿者的帮助,帮他找到路,PMP最多只能记住p距离的路线,志愿者总是会选择最好的路径,如果在p走不到时,会给他指向下一个在这条路径上的志愿者的位置,让我们求p的最小值
说实话这个地方我也看了很久,复述的也不太明白
直接说就是,有k个特殊的点,我记录从s到t的最短路径w,如果中间遇到了特殊节点,路径长度就清空w,那么这个w就是p的最小值
主要是题目没看懂,看懂了题目就很明白了,就是从起点出发,然后找最短路径,记录路径的长度,如果遇到了有志愿者的点,路径长度就清空为0 ,
用优先队列来实现,将与当前节点相连的路线放进优先队列,按照路线终点来排序(按照起点排序也行,起点排序跑的还更快),找到终点break即可,
code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll; typedef unsigned long long ull; typedef long double ld;
const ll MOD = 1e9 + 7;
#define pai pair<int, int>
const int N = 1e5 + 7;
const int INF = 0x3f3f3f3f;
struct node{
int u , w;
bool operator <(const node &a) const{
return u < a.u;
}
};
ll n , m , k;
vector<int>edge[N];
bool vis[N];
int s , t;
int dis[N];
int main(void){
cin>>n>>m>>k;
int x , u , v ,w;
for(int i = 1 ; i <= k ; ++i){
cin>>x;
vis[x] = 1;
}
for(int i = 1 ; i <= m ; ++i){
cin>>u>>v;
edge[u].push_back(v);
edge[v].push_back(u);
}
cin>>s>>t;
int ans = 0;
memset(dis , 0x3f , sizeof(dis));
priority_queue<pai , vector<pai> , greater<pai>> pq;
pq.push({0 , s});
while(pq.size()){
w = pq.top().first , u = pq.top().second;
pq.pop();
ans = max(ans , w);
if(u == t) break;
if(vis[u]) w = 0;
for(auto& v : edge[u]){
if(dis[v] > w + 1){
dis[v] = w + 1;
pq.push({dis[v] , v});
}
}
}
if(dis[t] == INF) ans = -1;
printf("%d\n" , ans);
return 0;
}

京公网安备 11010502036488号