• 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
    ");
    		else printf("Yes
    ");
    	}
    
    	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
    ");
    		else printf("Yes
    ");
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    DevOps
    DevOps
    微信的NATIVE支付提示201商户订单号重复的解决方案
    phpstorm 破解
    Git忽略已经被版本控制的文件(添加.gitignore不会起作用)
    微信 {"errcode":48001,"errmsg":"api unauthorized, hints: [ req_id: 1QoCla0699ns81 ]"}
    如何用AJax提交name[]数组?
    基于PHP给大家讲解防刷票的一些技巧
    为何GET只发一次TCP连接,POST发两次TCP连接
    IP地址在mysql的存储(IP地址和int的转换)
  • 原文地址:https://www.cnblogs.com/houzm/p/12240605.html
Copyright © 2020-2023  润新知