实话实说,这个题目本身并不算是太难,主要考察散列表,题目的目标是获得更快的查找速度。
下面博主就来说说我做这个题目的过程:
审完题,第一反应就是建立一个散列表来进行危险列表的存储,然后再逐个构建运输物品列表来进行判断。
刚开始没有考虑到一个物品可以与多个物品发生反应,因此使用了一对一模式,结果错了一片,不过想想也是,
于是就将对应模式改为了一对多,为了提高效率,map被我换成了一个大型数组,然后每个数组的元素是一个set。
列表建好了,就是核对每个运输列表是否合规了,首先使用一个set保存一个运输列表,然后遍历每个运输
列表中的元素,通过危险列表来判断是否有物品冲突,如果发现一个,则直接判断不合规,如果全部遍历完成
后都没有发现一个,则符合规定。
下面是C++写的代码:
#include <cstdio>
#include <set>
#include <algorithm>
using namespace std;
const int M = 100005;
set<int> list[M];
int main() {
//构建危险列表
int n,k,l,t1,t2,t3;
scanf("%d%d",&n,&k);
for (int i = 0; i < n; i++) {
scanf("%d%d",&t1,&t2);
list[t1].insert(t2);
list[t2].insert(t1);
}
//进行计算
for (int i = 0; i < k; i++) {
scanf("%d",&l);
set<int> c;
for (int j = 0; j < l; j++) {
scanf("%d",&t3);
c.insert(t3);
}
bool flag = true;
//遍历集合中所有元素,判断是否和危险列表冲突
for(const int &x:c){
if(!list[x].empty()){
for(const int &y:list[x]){
if (find(c.begin(),c.end(),y)!=c.end()){
flag = false;
goto out;
}
}
}
}
out:
printf("%s\n",flag?"Yes":"No");
}
return 0;
}