A1134 Vertex Cover (25 分| hash散列,附详细注释,逻辑分析)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_24452475/article/details/100549560

写在前面

  • 思路分析
    • 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;
    }
    

猜你喜欢

转载自blog.csdn.net/qq_24452475/article/details/100549560