BFS——小妈妈找蝌蚪
题目描述
青蛙妈妈最近很不放心把蝌蚪宝宝送到幼儿园,但当她买菜回家时,却发现可爱的孩子小蝌蚪走丢了。
小池塘里有很多石头,青蛙家在其中标号为s的石头上。小蝌蚪会移动k分钟,每分钟会出现在任意石头旁边,甚至多次出现在一块石头旁边。但k分钟之后,蝌蚪宝宝就游不动了。
青蛙妈妈第0秒从家所在的石头出发,每分钟移动一次,可以留在原地,也可以跳跃到一块当前可跳跃到的石头上(只能在特定的石头间双向跳跃)。
输入描述:
多组数据。
第一行输入石头个数n,青蛙妈妈可以跳跃的石头对数m,蝌蚪宝宝的活动时间k,青蛙家所在的石头s。
之后输入k个数,其中第i个数代表第i分钟蝌蚪宝宝的位置,编号从i=1开始。
接下来输入m行,每行包括两个数ui,vi,表示青蛙妈妈可以在第ui个和vi个石头间双向跳跃。
输出描述:
请输出青蛙妈妈最少几分钟发现蝌蚪宝宝。
示例
输入
3 2 2 1
2 1
1 2
1 3
5 5 3 5
3 1 4
1 2
2 3
2 4
3 4
4 5
输出
1
3
备注:
1≤n≤100000,
1≤m≤2∗n,
1≤k≤100000,
1≤s≤n,
1≤u,v≤n,
无重边,无自环,保证联通,
数据不多于10组
分析
这题可以分成两种情况,第一种在k分钟之内,妈妈就找到小蝌蚪了,对于这种情况,就要找妈妈到达每块石头的最短时间,并从前往后遍历,如果到达某块石头的最短时间小于或等于小蝌蚪到达这块石头的时间,那么小蝌蚪到达这块石头的时间,就是妈妈可以找到小蝌蚪的最少时间。第二种情况是在k分钟以后,妈妈才找到小蝌蚪,这种情况下,说明在k分钟之内,妈妈到达每块石头的最短时间都大于小蝌蚪到达这块石头的时间,并不能找到,而k分钟后,小蝌蚪已经游不动了,只能待在一个地方,此时只要输出妈妈到达小蝌蚪此时所在石头的最少时间即可。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
const int maxn=1e5+5;
const int inf=0x3f3f3f3f;
int n,m,k,s;
int vis[maxn],dis[maxn];
vector<int> f[maxn];
void bfs(int src)
{
queue<int> q;
q.push(src);
while(!q.empty()){
int p=q.front();
q.pop();
for(int i=0;i<f[p].size();i++){
int c=f[p][i];
if(vis[c]>vis[p]+1){
vis[c]=vis[p]+1;
q.push(c);
}
}
}
}
int main()
{
while(cin>>n>>m>>k>>s){
int flag=0;
for(int i=1;i<=k;i++){
cin>>dis[i];
}
for(int i=0;i<m;i++){
int a,b;
cin>>a>>b;
f[a].push_back(b);
f[b].push_back(a);
}
for(int i=1;i<=n;i++){
vis[i]=inf;
}
vis[s]=0;
bfs(s);
for(int i=1;i<=k;i++){
if(vis[dis[i]]<=i){
cout<<i<<endl;
flag=1;
break;
}
}
if(!flag){
cout<<vis[dis[k]]<<endl;
}
for(int i=0;i<m;i++){
f[i].clear();
}
}
return 0;
}