• PAT甲级1134Vertex Cover


    题目链接

    https://pintia.cn/problem-sets/994805342720868352/problems/994805346428633088

    题目要求

    • vertex cover

      vertex cover指图中的每条边都和这组顶点中至少一个顶点相关,先给定一个图和几组顶点,请判断这几组顶点是否为vertex cover

    • 输入

      • N:顶点数量,不超过10000

      • M:边的数量,不超过10000

      • M条边:顶点通过[0,N-1]表示/索引

      • K:有几组顶点,不超过100

      • K组顶点

        一组顶点的第一个数字是顶点数量,剩下的是顶点索引

    • 输出

      • 是vertex则输出Yes,不是则输出No

    题解一

    思路

    • 定义Edge结构体,包括两个端点

    • 把M条边存入vector

    • 将顶点组存入set(vector也可以)

    • 遍历每条边判断其两个端点是否在set中

      只要有一条边的两个端点都不在set中,则不是vertex cover

    代码

    // Problem: PAT Advanced 1134
    // URL: https://pintia.cn/problem-sets/994805342720868352/problems/994805346428633088
    // Tags: Graph Hash Set
    
    #include <iostream>
    #include <set>
    #include <vector>
    using namespace std;
    
    struct Edge{
        int v1, v2;
    };
    
    int main()
    {
        int n, m, k;
        scanf("%d %d", &n, &m);
        
        vector<Edge> edges(m); // 存储边
        for (int i = 0; i < m; i++)
            scanf("%d %d", &edges[i].v1, &edges[i].v2);
    
        scanf("%d", &k);
        while (k--){
            set<int> vertices;
            int vertexNum, vertex;
            scanf("%d", &vertexNum);
            for (int i = 0; i < vertexNum; i++){ // 将一组顶点存入set
                scanf("%d", &vertex);
                vertices.insert(vertex);
            }
    
            bool isVertexCover = true;
            for (auto it = edges.begin(); it != edges.end(); it++){
                // 只要有一条边的两个端点都不在set中,则不是vertex cover
                if (vertices.find(it->v1) == vertices.end() && vertices.find(it->v2) == vertices.end()){
                    isVertexCover = false;
                    break;
                }
            }
            if (isVertexCover)
                printf("Yes
    ");
            else
                printf("No
    ");
        }
        return 0;
    }
    

    题解二

    比上一个方法快

    思路

    • 给M条边编号为[0,M-1]
    • 读取每条边时,保存每个顶点与哪条边相关,将这个信息存入vector
    • 定义vector表示各条边是否被覆盖,遍历上一步得到的vector标记各条边是否被覆盖,最后遍历这一步定义的vector判断是否符合vertex cover的条件

    注意点

    • 一个顶点可以和多条边相关

    代码

    // Problem: PAT Advanced 1134
    // URL: https://pintia.cn/problem-sets/994805342720868352/problems/994805346428633088
    // Tags: Graph Hash Set
    
    #include <iostream>
    #include <vector>
    using namespace std;
    
    int main()
    {
        int n, m, k;
        scanf("%d %d", &n, &m);
    
        vector<int> cover[n]; // cover[2].push_back(3) 代表顶点2覆盖了边3
        int v1, v2;
        for (int i = 0; i < m; i++){
            scanf("%d %d", &v1, &v2);
            cover[v1].push_back(i);
            cover[v2].push_back(i);
        }
    
        scanf("%d", &k);
        while (k--){
            vector<bool> isCovered(m, false); // m条边是否被覆盖
            int vertexNum, vertex;
            scanf("%d", &vertexNum);
            for (int i = 0; i < vertexNum; i++){ // 遍历顶点,将其覆盖的边标记
                scanf("%d", &vertex);
                for (int j = 0; j < cover[vertex].size(); j++)
                    isCovered[cover[vertex][j]] = true;
            }
            bool isVertexCover = true;
            for (int i = 0; i < m; i++){
                if (isCovered[i] == false){
                    isVertexCover = false;
                    break;       
                }
            }
            if (isVertexCover)
                printf("Yes
    ");
            else
                printf("No
    ");        
        }
        return 0;
    }
    

    参考链接

    https://blog.csdn.net/liuchuo/article/details/78037329


    作者:@臭咸鱼

    转载请注明出处:https://www.cnblogs.com/chouxianyu/

    欢迎讨论和交流!


  • 相关阅读:
    Java获取一年里某季、某月、某周的第一天及最后一天时间的完整代码如下:
    django 将数组交给前台
    模板标签
    django 变量交给前台模板
    内核解密 | Oracle 18c 数据库安装ORA-12754的两种解决方案
    浅谈大型web系统架构
    浅谈大型web系统架构
    浅谈大型web系统架构
    浅谈大型web系统架构
    微信小程序把玩(三十二)Image API
  • 原文地址:https://www.cnblogs.com/chouxianyu/p/13599098.html
Copyright © 2020-2023  润新知