PAT-A 真题 – 1134 Vertex Cover

发布于 / PAT-甲级 / 0 条评论

vertex cover of a graph is a set of vertices such that each edge of the graph is incident to at least one vertex of the set. Now given a graph with several vertex sets, you are supposed to tell if each of them is a vertex cover or not.

Input Specification:

Each input file contains one test case. For each case, the first line gives two positive integers N and M (both no more than 104), being the total numbers of vertices and the edges, respectively. Then M lines follow, each describes an edge by giving the indices (from 0 to N1) of the two ends of the edge.

After the graph, a positive integer K ( 100) is given, which is the number of queries. Then K lines of queries follow, each in the format:

Nv v[1] v[2]v[Nv]

where Nv is the number of vertices in the set, and v[i]'s are the indices of the vertices.

Output Specification:

For each query, print in a line Yes if the set is a vertex cover, or No if not.

Sample 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

Sample Output:

No
Yes
Yes
No
No

题目大意:给定一个图,接着给出几个点,判断是不是图中的任意一条边都会途径这个点

这道题可以把每个边设置一个编号,我这里设置边号的策略是,用size_t的前5位表示连成边的两个点的数字中较小的一个,后5位是较大的一个,这样就可以保证每一条边的边号都具有唯一性了。

在存储图时,使用邻接表来存储,在查询时,每输入一个点,标记与这个点所连接的所有边已访问。并将计数器+1

这个映射关系可以用unordered_map<size_t, bool>来存储(直接用map运行时间580ms,有超时的风险)

接着判断最终计数器是否等于总边数(即所有边都访问过,边上的任一点都会途径给定的点集)

代码:

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const size_t maxn = 10010;
vector<int> G[maxn];  //邻接表 

size_t Hash(int a, int b){
  if(a > b) swap(a, b);  //保证 a<b,两点之间的边的id具有唯一性 
  return a * 100000 + b;
}

int main(){
  int vcnt, ecnt, qcnt;
  scanf("%d %d", &vcnt, &ecnt);
  for(int i = 0; i < ecnt; i++){
    int _l, _r;
    scanf("%d %d", &_l, &_r);
    G[_l].push_back(_r);
    G[_r].push_back(_l);
  }
  scanf("%d", &qcnt);
  for(int i = 0; i < qcnt; i++){  //对于每一个查询 
    unordered_map<size_t, bool> H;
    int K, __cnt = 0;
    scanf("%d", &K);
    for(int j = 0; j < K; j++){  //读入要查询的所有点 
      int v;
      scanf("%d", &v);
      for(auto it : G[v]){  //遍历与该点连接的所有边
        size_t _hash = Hash(v, it);  //获取这个边的id 
        if(H[_hash] == 0){  //边没访问过
          __cnt++;  //计数器++ 
          H[_hash] = 1;  //标记已访问 
        }
      }
    }
    if(__cnt == ecnt) printf("Yes\n");
    else printf("No\n");
  } 
  return 0;
}

转载原创文章请注明,转载自: 斐斐のBlog » PAT-A 真题 – 1134 Vertex Cover
目前还没有评论,快来抢沙发吧~