PAT Advanced 1134 Vertex Cover (25) [hash散列]

题目

A 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 N-1) of the two ends of the edge. Afer 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

题目分析

给出图的每条边顶点信息,给出几组顶点集合,判断顶点集合是否是vertex cover(vertex cover指:一个顶点集合,图每条边的顶点至少有一个在这个顶点集合中)

解题思路

算法 1

  1. 定义顶点结构体edge,两个顶点left,right
  2. 定义vector v,存放图每条边的信息
  3. 定义int ves[N],存放每个查询顶点集合中顶点出现次数
  4. 每个顶点集合的判断,需要遍历所有边信息
    • 每条边的两个顶点至少有一个在顶点集合中,满足条件,打印Yes
    • 只要有一条边的两个顶点都不在顶点集合中,不满足条件,打印No

算法2

  1. 定义一个vector数组,数组下标表示顶点,vector中存放的是该顶点所在边的编号
  2. 每次校验一个顶点集合,定义一个int hash[M]数组,下标为图的边,值为边的顶点是否至少有一个在顶点集合中,若边满足条件置为1
  3. 遍历hash[M]数组,是否所有元素都为1,表示每条边至少有一个顶点在顶点集合中,该顶点集合是vertex cover

Code

Code 01(算法1 最优)

#include <iostream>
#include <vector>
using namespace std;
struct edge {
	int left,right;
};
int main(int argc,char * argv[]) {
	int N,M,K,L,V;
	scanf("%d %d", &N,&M);
	edge es[M];
	for(int i=0; i<M; i++) {
		scanf("%d %d",&es[i].left,&es[i].right);
	}
	scanf("%d",&K);
	for(int i=0; i<K; i++) {
		scanf("%d", &L);
		int ves[N]= {0};
		for(int j=0; j<L; j++) {
			scanf("%d",&V);
			ves[V]++;
		}
		int j;
		for(j=0; j<M; j++) {
			if(ves[es[j].left]==0&&ves[es[j].right]==0)break;
		}
		if(j!=M)printf("No\n");
		else printf("Yes\n");
	}

	return 0;
}

Code 02(算法2)

#include <iostream>
#include <vector>
using namespace std;
int main(int argc,char * argv[]) {
	int N,M,K,L,V;
	scanf("%d %d", &N,&M);
	vector<int> es[N];
	int f,r;
	for(int i=0; i<M; i++) {
		scanf("%d %d",&f,&r);
		es[f].push_back(i);
		es[r].push_back(i);
	}
	scanf("%d",&K);
	for(int i=0; i<K; i++) {
		scanf("%d", &L);
		int hash[M]= {0};
		for(int j=0; j<L; j++) {
			scanf("%d",&V);
			for(int t=0; t<es[V].size(); t++) {
				hash[es[V][t]]=1;
			}
		}
		int j;
		for(j=0; j<M; j++) {
			if(hash[j]==0) {
				break;
			}
		}
		if(j!=M)printf("No\n");
		else printf("Yes\n");
	}

	return 0;
}
posted @ 2020-01-29 16:19  JamieHou  阅读(111)  评论(0编辑  收藏  举报