L3-2. 喊山 (DFS)
喊山,是人双手围在嘴边成喇叭状,对着远方高山发出“喂—喂喂—喂喂喂……”的呼唤。呼唤声通过空气的传递,回荡于深谷之间,传送到人们耳中,发出约定俗成的“讯号”,达到声讯传递交流的目的。原来它是彝族先民用来求援呼救的“讯号”,慢慢地人们在生活实践中发现了它的实用价值,便把它作为一种交流工具世代传袭使用。(图文摘自:http://news.xrxxw.com/newsshow-8018.html)
![](https://www.patest.cn/upload/la_o7tlnpg1nvo.jpg)
一个山头呼喊的声音可以被临近的山头同时听到。题目假设每个山头最多有两个能听到它的临近山头。给定任意一个发出原始信号的山头,本题请你找出这个信号最远能传达到的地方。
输入格式:
输入第一行给出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
可以抽象为题目给了一个边权值为1的无向稀疏图可以直接DFS强搜!
因为本题可能存在一个环,否则可能会误判起始点的相邻点为最远点,我就是一开始没看懂题意。!!!o( ̄ヘ ̄o#) !
例如:
2—4
| |
1—3
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
int n,m,k;
int vis[10005],dis[10005];
struct node
{
int v;
struct node*next;
}head[10005];
void add(int u,int v)
{
struct node*p=new node;
p->v=v;
p->next=head[u].next;
head[u].next=p;
}
void dfs(int st,int sum)
{
struct node *p=head[st].next;
for(;p!=NULL;p=p->next)
{
int v=p->v;
if(!vis[v])
{
vis[v]=1;
dfs(v,sum+1);
vis[v]=0;
}
}
dis[st]=min(dis[st],sum);
}
void print()
{
int Max=0;
int i;
int ans=0;
// for(i=1;i<=n;++i)
// {
// printf("%d ",dis[i]);
// }
// printf("\n");
for(i=1;i<=n;++i)
{
if(dis[i]>Max&&dis[i]!=inf)
{
Max=dis[i];
ans=i;
}
if(dis[i]==Max&&i<ans)
{
ans=i;
}
}
printf("%d\n",ans);
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
int i;
int u,v;
for(i=1;i<=n;++i)
{
head[i].next=NULL;
}
for(i=0;i<m;++i)
{
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
int st;
while(k--)
{
scanf("%d",&st);
for(i=1;i<=n;++i)
{
vis[i]=0;
dis[i]=inf;
}
dis[st]=0;
vis[st]=1;
dfs(st,0);
print();
}
return 0;
}