L3-008 喊山
题目
一个山头呼喊的声音可以被临近的山头同时听到。题目假设每个山头最多有两个能听到它的临近山头。给定任意一个发出原始信号的山头,本题请你找出这个信号最远能传达到的地方。
输入格式:
输入第一行给出3个正整数n、m和k,其中n(≤10000)是总的山头数(于是假设每个山头从1到n编号)。接下来的m行,每行给出2个不超过n的正整数,数字间用空格分开,分别代表可以听到彼此的两个山头的编号。这里保证每一对山头只被输入一次,不会有重复的关系输入。最后一行给出k(≤10)个不超过n的正整数,数字间用空格分开,代表需要查询的山头的编号。
输出格式:
依次对于输入中的每个被查询的山头,在一行中输出其发出的呼喊能够连锁传达到的最远的那个山头。注意:被输出的首先必须是被查询的个山头能连锁传到的。若这样的山头不只一个,则输出编号最小的那个。若此山头的呼喊无法传到任何其他山头,则输出0。
输入样例:
7 5 4
1 2
2 3
3 1
4 5
5 6
1 4 5 7
输出样例:
2
6
4
0
看完题目 , 第一想法就是DFS暴力解决 , 最后测试点1和测试点2没过 , 无奈又重新审题查错 , 发现这个题是明显分层的 , 应该使用BFS , 附上一组自己的测试样例 :
输入 :
6 7 1
1 2
1 3
2 3
2 4
3 5
3 6
5 6
1
正确输出应该是4(但是我写的DFS输出的5
最终满分的BFS题解 :
#include<bits/stdc++.h>
using namespace std;
int n,m,k;//n : 总的山头数 , m行 : 每行两个山头的编号 , k 要查询的山头的编号
//山头从1到n编号
int vis[10001],sign[10001],level[10001],maxLevel=10001,minIndex;
vector<vector<int>>nodes;
//BFS层序遍历 , 找到层数最大的 且 编号最小的 山头
void bfs(int s){
queue<int>q;
q.push(s);
vis[s]=1;
while(!q.empty()){
int now=q.front();
q.pop();
for(int i=0;i<nodes[now].size();++i){
int nxt=nodes[now][i];
if(vis[nxt]) continue;
q.push(nxt);
vis[nxt]=1;
level[nxt]=level[now]+1;
if(level[nxt]>maxLevel){
maxLevel=level[nxt];
minIndex=nxt;
}else if(level[nxt]==maxLevel){
if(minIndex>nxt){
minIndex=nxt;
}
}
}
}
}
int main(){
cin>>n>>m>>k;
nodes.resize(n+1);
for(int i=1;i<=m;++i){
int a,b;
cin>>a>>b;
nodes[a].push_back(b);
nodes[b].push_back(a);
sign[a]=sign[b]=1;
}
for(int i=0;i<k;++i){
int s;
cin>>s;
maxLevel=-1;
minIndex=10001;
fill(vis,vis+10001,0);
fill(level,level+10001,0);
if(0==sign[s]){
cout<<"0"<<endl;
continue;
}
bfs(s);
cout<<minIndex<<endl;
}
return 0;
}
后续我会继续研究研究这个题用DFS该如何解决 , 如有大佬有DFS的解决方案 , 可以留言分享一下 , 互帮互助 , 共同进步QwQ