英文题目:1134 Vertex Cover - PAT (Advanced Level) Practice (pintia.cn)
题意解析
首先给n个点m条边,我们去建图,然后再给我们K个顶点,让我们判断这k个顶点是否落在图中的每一条边的顶点上。(一条边至少落一个顶点),如果满足输出“yes”,否则输出“No”。
样例模拟
这是根据样例画的9个节点10条边:
这是第一个询问,0 3 8 4:
我们发现1~2这条边和1~9这条边没有1个顶点在给定的图中,输出“NO”:
第二个询问,6,1,7,5,4,9:
我们发现每条边都至少有一个顶点位于图中,输出“yes”。
第三个询问,1,8,4:
我们发现每条边都至少有一个顶点位于图中,输出“yes”。
第四个询问,2,8:
我们发现 1~0,1~9,1~4,4~5 这几条边没有1个顶点在图中,输出“NO”:
第五个询问,9 8 7 6 5 4 2
我们发现1~0这条边没有1个顶点在图中,输出"NO":
code
每次询问使用bool st[N]保存访问到的点
遍历所有边,一个边至少有1个点被访问,否则输出No
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
//复杂度
//最多10000条边,100次询问,每次询问访问的点不超过10000,最多1e6
//思路:
//1. 将组合每一条边的两个点保存到集合中
int n,m;
vector<pair<int,int>> arr;
//2. 每次询问使用bool st[N]保存访问到的点
const int N = 10010;
bool st[N];
//3. 遍历所有边,一个边至少有1个点被访问,否则输出No
int main(){
cin >> n >> m;
while(m--){
int a,b; //组成边的a和b两点
cin >> a >> b;
arr.push_back({a,b});
}
int q; //query
cin >> q;
while(q--){
memset(st,false,sizeof st);
int k; //每次询问,访问的总点数
cin >> k;
while(k--){
int a; //访问的点
cin >> a;
st[a] = true;
}
int i = 0;
for(; i < arr.size(); i++){
if(!st[arr[i].first] && !st[arr[i].second]) break;
}
if(i == arr.size()) puts("Yes"); //如果能走到末尾,说明每个点都被遍历到了
else puts("No");
}
return 0;
}