题目链接:acwing 1471. 牛奶工厂
题目大意
给出 n 个点,一共有 n-1 条边,问是否存在一个点 i,使得所有其它点能够直接或间接( 经过其他点到达点 i 或者直达点 i )的到达点 i,如果有,请输出最小的 i。
题意解析
最容易想到的方法就是用邻接表存储图。
- 建一个哈希表,将第一个点到最后一个点所能到达的所有其他点的对应键值++。
- 遍历哈希表,找到键值为 n-1 的点,也即是有除它之外的所有点都能够到达它。
这里有个小细节就是哈希表可以使用 map,因为 map 可以自动排序,我们只需要从头遍历每一个点对应的键值是否为 n-1,然后输出,这就是最小的 i。
当然也有其他方法可以做,有兴趣可以点击题目链接去看看其他的题解。
代码(c++)
#include<iostream>
#include<cstring>
#include<queue>
#include<map>
using namespace std;
const int N=1e5+10;
int h[N],e[N],ne[N],idx;
map<int,int> mp;
int n,m;
void add(int a,int b) //邻接表建图
{
e[idx]=b; ne[idx]=h[a]; h[a]=idx++;
}
void bfs(int u) //图的遍历
{
queue<int>q;
q.push(u);
while(q.size())
{
int t=q.front(); q.pop();
for(int i=h[t];i!=-1;i=ne[i])
{
mp[e[i]]++;
q.push(e[i]);
}
}
}
int main()
{
cin>>n;
memset(h, -1, sizeof h);
for(int i=0;i<n-1;i++)
{
int a,b;
cin>>a>>b;
add(a,b);
}
for(int i=1;i<=n;i++) bfs(i);
for(auto x : mp)
{
if(x.second==n-1) //找到第一个i
{
cout<<x.first<<endl;
return 0;
}
}
cout<<-1<<endl;
return 0;
}