版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
写在前面
- 思路分析
vector v[n]
保存某结点属于某条边编号,比如a b两个结点构成边的编号为0,则v[a].push_back(0), v[b].push_back(0)
——表示a属于0号边, b也属于0号边。- 对于每1个集合做判断,遍历集合中每1个元素,将当前元素能够属于的边的编号i对应的
hashs[i]
标记为1,表示这条边是满足有1个结点出自集合S中的。 - 判断
hashs
数组中每1个值是否都是1,如果有不是1,说明边的两结点均不在集合S中,输出No。 - 否则输出Yes
- 耗费时间点
- 理解题意
- 判断1个集合的点是否覆盖给定图的所有边
- hash映射思想
- 理解题意
测试用例
-
input: 10 11 8 7 6 8 4 5 8 4 8 1 1 2 1 4 9 8 9 1 1 0 2 4 5 4 0 3 8 4 6 6 1 7 5 4 9 3 1 8 4 2 2 8 7 9 8 7 6 5 4 2 output: No Yes Yes No No
ac代码
-
#include <iostream> #include <cstdio> #include <algorithm> #include <vector> #include <map> #include <set> #include <string> #include <cctype> #include <unordered_map> using namespace std; int main() { int n, m, k, nv, a, b, num; scanf("%d%d", &n, &m); vector<int> v[n]; for(int i=0; i<m; i++) { scanf("%d%d", &a, &b); v[a].push_back(i); v[b].push_back(i); } scanf("%d", &k); for(int i=0; i<k; i++) { scanf("%d", &nv); int flag = 0; vector<int> hashs(m, 0); for(int j=0; j<nv; j++) { scanf("%d", &num); // 与某顶点关联的所有边,置为1 for(int t=0; t<v[num].size(); t++) hashs[v[num][t]] = 1; } for(int j=0; j<m; j++) { // 存在未遍历到的边 if(hashs[j]==0) { printf("No\n"); flag = 1; break; } } if(flag == 0) printf("Yes\n"); } return 0; }